diff --git a/NEWS b/NEWS index b7380a9877..66886a0968 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,493 @@ +Overview of Changes from GTK+ 2.18.0 to 2.18.1 +============================================== + +* Client-side Windows: + - Fix a problem with the F-Spot screensaver + - Request native events that are necessary for grab emulation + - Fixes for input device and extended input event handling + - Allow up to 255 buttons in extended input events + +* OS X: + - Improve handling of multi-monitor setups + - Basic DND works + - Other improvements + +* Filechooser: + - Support Tracker 0.7 in the search code + +* Bugs fixed: + 596423 Landscape pages are the wrong way around + 588449 DnD doesn't work on GDK/Quartz + 596080 Mention "gtk-tooltip" in gtk_widget_set_tooltip_window + 596580 Blank rows in entry autocompletion + 588649 extended input events sent to widgets that didn't... + 596081 Update tracker support for version 0.7 + 596345 clicking empty space in backgrounds... + 596494 New property "cursor" in 2.18's GdkWindow with wrong... + 596012 popup menu position is horribly off on gdk quartz... + 596250 Gdkcursor-quartz.c doesn't implement GDK_BLANK_CURSOR + 586207 Printing dialog with a CUPS printer connected... + +* Translation updates: + Assamese + British English + Czech + Estonian + French + Galician + German + Hungarian + Slovenian + Spanish + Swedish + + +Overview of Changes from GTK+ 2.17.11 to 2.18.0 +=============================================== + +* Add GtkTreeModelFilter testsuite and fix multiple bugs + +* Client-side windows: + - Fix issues around recursion and gdk_window_process_updates + - Fix issues with grabs and cursors + - Handle window hierarchy and geometry changes in expose handlers + - New function, gdk_window_flush, that may be needed in certain + situations + - Automatically flush windows when doing non-double-buffered exposes + +* Quartz backend: + - Fix various 'stuck UI' issues + - Fix the size of the root window + +* Bugs fixed: + 588455 run application broken when setting background color... + 346800 Rework sort/filter models to use indices to parents + 593678 select "Manage Custom Sizes" from print dialog hangs gedit + 594652 gtk printer dialog does not understand boolean printer options + 594668 Add new Xorg keysyms + 591583 Padre (a wxPerl+Gtk IDE) hangs when editing Perl code... + 594600 Windows only allows 64-character system-tray tooltips + 594679 Fix warning in testwindows.c + 594880 Drawing issues in ExoIconView + 593507 AbiWord's main drawing area not exposed properly + 594913 is_composited race ... + 594738 Windows often do not respond to events on dual-head + 503776 crash when trying to print to non-existent lpr printer + 595599 Don't focus unmapped radio buttons + 595790 Segfault in gtkiconfactory.c on NULL GError + 588649 extended input events sent to widgets that didn't... + 550939 GtkFileChooser listbox does not refresh selection + +* New deprecation: + gdk_event_get_graphics_exposes has been deprecated + +* Updated translations: + Afrikaans + Assamese + Bengali India + Brazilian Portuguese + British English + Catalan + Danish + Dutch + German + Greek + Gujarati + Hindi + Italian + Japanese + Lithuanian + Maithili + Malayalam + Marathi + Norwegian bokmål + Oriya + Polish + Romanian + Simplified Chinese + Slovenian + Traditional Chinese + Ukrainian + + +Overview of Changes from GTK+ 2.17.10 to 2.17.11 +================================================ + +* Client-side windows: + - Add gdk_cairo_reset_clip that lets you get back the original + drawable clip + - Add gdk_window_restack to more conveniently restack child windows + - Add gdk_window_is_destroyed as a replacement for GDK_WINDOW_DESTROYED + - Deprecated GDK_WINDOW_OBJECT and GdkWindowObject + +* GSEAL: + - Add gtk_widget_set_receives_default and gtk_widget_get_receives_default + accessors for GTK_RECEIVES_DEFAULT + +* GtkTreeView: + - Correctly propagate insensitive state to cell renderers + +* GtkTextView: + - Merge a number of scrolling-related fixes from Maemo + +* Bugs fixed: + 564160 gtk_combo_box_entry_set_text_column too restrictive + 593868 gtk_im_multicontext_set_client_window recreate a new slave... + 593644 gdk_x11_screen_get_window_manager_name should not cache... + 594178 gdk-pixbuf-query-loaders segfault in write_loader_info + 567124 proposal to delay doing something related to immodule... + 588788 GTK+ compilation should work with automake1.10 + 584638 Build of gtkupdateiconcache without NLS breaks + 593788 misprint in the returning value of gdk_selection_property_get + 593606 Missing include in gtk/gtkcellrendereraccel.c + 593877 Undefined symbols while compilation + +* Translation updates: + French + Hebrew + Hungarian + Norwegian bokmål + + +Overview of Changes from GTK+ 2.17.9 to 2.17.10 +=============================================== + +* Client-side windows: + - Regression fixes continue + - Multiple clipping issues have been fixed + - gdk_window_beep() works again + - gtk-demo now has a few offscreen window demos + +* GSEAL: + - Several more getters and setters have been added: + gtk_widget_is_toplevel(), gtk_widget_is_drawable(), gtk_widget_set_window() + +* Bugs fixed: + 592752 aisleriot card drag start makes card appear behind... + 592901 Crash in JPEG pixbuf loader instead of error + 592263 redraw problem in text view + 593011 Cannot move applet with middle click + 592624 BadAccess from gdk_window_x11_set_events + 592606 Activate the default button in a respose-request callback + 593249 emacs and acroread don't work properly + 592883 Spin cell rendererer problem with double click + 588199 GtkTreeView rendering glitch while using a default... + 543310 set_enable_tree_lines doesn't work when a cellrenderer... + 589636 csw broke DND from panel menus + 593595 broken clip handling in GtkLabel + 590921 NULL should not be a valid return value for gdk_window_new() + 590861 cups_printer_create_cairo_surface() sets a fallback resolution... + 544724 delete new line requires two keystrokes + 593001 Emit 'update-custom-widget' on page setup change + 593317 gtkwindow leaks startup ID + 593080 mem leak + 593481 GtkEntryCompletion action-activated signal is emitted... + 593135 gtk_entry_set_icon_from_pixbuf only works one time + 593012 configure doesn't handle --enable-{cups,papi} correctly + 592862 There is a misprint on the returning value of gdk_pixmap_lookup() + 586466 GtkPrintOperation printing fails if it is the only event source + 434318 printer detail acquisition needs events + 593712 configure fails to to check properly for cups... + +* Translation updates: + Asturian + Basque + Bengali India + Czech + Finnish + Hindi + Kannada + Oriya + Polish + Serbian + Tamil + Telugu + + +Overview of Changes from GTK+ 2.17.8 to 2.17.9 +============================================== + +* Client-side windows: + - Add a compatibility mode that falls back to always using native windows, + triggered by the GDK_NATIVE_WINDOWS environment variable + +* Bugs fixed: + 589367 gedit crashed with SIGSEGV in IA__g_list_last() + 478519 GtkTooltip segfaults on NULL gdk-display-current-tooltip. + 592461 preserve errno and use g_strerror + 592403 crash when close the second terminal... + 591549 Default printer in a network + 526149 GtkCellRendererAccel editing conflicts with mnemonics + 528283 Problems when using PageUp & PageDown to navigate Playlists pane + +* Updated translations: + Bengali + Brazilian Portuguese + Breton + Bulgarian + Catalan + Estonian + Galician + Irish + Korean + Norwegian bokmål + Portuguese + Punjabi + Spanish + Swedish + Thai + + +Overview of Changes from GTK+ 2.17.7 to 2.17.8 +============================================== + +* Client-side windows: + - various fixes to expose handling + - fix memory leaks + +* Minor API additions: + - New setter as part of the GSEAL effort: gtk_widget_set_allocation + +* Bugs fixed: + 585211 Add accessor function for GtkWidget->allocation + 588437 gtk 2.17.3 causes dragging in firefox bookmarks sidebar t... + 589367 gedit crashed with SIGSEGV in IA__g_list_last() + 589877 Client side windows leak gdk regions + 590959 Set child_has_focus flag properly + 591432 There is incomplete information on the returning value of... + 591434 firefox-3.5 crashed with SIGSEGV in _gdk_window_process_u... + 591526 Accelerator keys with modifier also triggered by ... + 591751 bad memory access with duplicated id + 591998 Support silent build rules with automake 1.11 + 592003 Shift+click should always modify selection + +* Updated translations: + Brazilian + Bulgarian + Irish + Swedish + + +Overview of Changes from GTK+ 2.17.6 to 2.17.7 +============================================== + +* Client-side windows: a number of regressions related to embedding + have been fixed + +* Printing: The file backend supports SVG output + +* Minor API additions: + - GtkIconView gained an icon-padding property that can be used to fine-tune + how much space each column needs + - GtkTreeViewColumn grew a sort-column-id property that can be used to set + up sort columns in GtkBuilder files + - GdkWindow gained a cursor property and associated getter + - GtkFileChooser has a create-folders property to allow disabling the + "New Folder" button + - gtk_print_operation_get_n_pages_to_print: returns the number of pages + that are being printed + - New getters and setters as part of the GSEAL effort: + gtk_widget_get_allocation, gtk_widget_get_visible, gtk_widget_set_visible + +* Bugs fixed: + 589336 Add GtkTreeViewColumn:sort-column-id property + 534462 Disable interactive search in the file chooser's shortcuts pane + 161489 n the file chooser, let the left/right arrow keys switch focus... + 514260 Better filtering for "Recently Used" files + 509650 ATK_STATE_SHOWING state is not set properly on menu items + 586374 code does not follow documentation (-> carshes when using... + 590442 csw broke gvim x11 embedding + 498010 gtk_tree_view_set_cursor fails if model!=NULL + 555109 Synthesized crossing events should have proper coordinates + 570516 Can't disable folder creation + 573321 additional check in gtk_tree_model_filter_convert_child_i... + 576601 Double clicking prints to the wrong printer + 586100 ITEM_PADDING breaks vertical icon views + 588438 awn uses 100% cpu with gtk+ 2.17.3 (csw) + 589732 behavior change of gdk_window_get_type_hint + 589745 Apply message in GtkAssistant + 590084 print to FILE with multiple pages per sheet has bad results + 590086 configure.in is broken on non-X platforms + 590309 Default cover pages for CUPS printers incorrectly set + 590448 [win32] build fails because gdk-pixbuf manges a path + 590959 Set child_has_focus flag properly + 591288 compat problem with draw_drawable being NULL + 539377 Unnecessary warnings when GtkTreeView is not realized. + 546005 priv->tree is not created for unrealized (I think) treeview + 564695 Pressing enter key in print to file "Name" box does not p... + 591218 Remove some unused variables + 357655 "Print to SVG file" for GtkPrintOperation + 591462 gdk_window_set_cursor doesn't work on the root window + +* Updated translations: + Basque + Brazilian Portuguese + Breton + Estonian + Galician + Hebrew + Norwegian bokmål + Spanish + Swedish + + +Overview of Changes from GTK+ 2.17.5 to 2.17.6 +============================================== + +* Client-side windows: + - Several optimizations, such as client-side tracking of + viewable windows + - Clipping for drawing pixbufs on windows has been fixed + - Rendering to large subwindows has been fixed + +* Changes that are relevant for translators: + - Markup has been removed from several strings + +* Bugs fixed: + 588398 Leak with testgtk::preview_(color|gray) and more + 588943 set correct selection before emitting cursor-changed... + 588076 Gnumeric fonts stopped working on upgrading gtk+ 2.17.2 -... + 574674 GtkMenuItem gets Selected and Focused states when SelectC... + 582674 Menu item and menu accessibles retain "showing" state aft... + 588553 [csw] gdk_draw_pixbuf doesnt draw outside expose events s... + 588897 Strange include x11/gdkx.h + 588958 Typo in startup-id window property + 589035 Context needed for a propoer translation + 589275 [csw] Trying to destroy NULL regions + 588964 Remove markup from translatable string in gtkfilechooserd... + 587337 Suggest to use Glade instead gtk-builder-convert script + +* Updated translations: + Estonian + French + Spanish + Swedish + Thai + + +Overview of Changes from GTK+ 2.17.4 to 2.17.5 +============================================== + +* Client-side windows: + - Quite a few fixes have happened for the win32 and directfb backends + +* GSEAL: + - Accessors have been added for sealed members in GtkCellRenderer and + GtkWidget + +* Changes that are relevant for distributors: + - The jpeg2000 pixbuf loader is now optional. Pass --with-libjasper + to configure to build it + +* Bugs fixed + 588373 Menus broken by client-side-windows + 588379 testgtk::panes does not change the cursor on mouse over + 588388 shape rendering is back + 588461 gtk_editable_get_chars() behaviour change in 2.17.4 + 588666 Incorrect clamping of max_length + 588665 insert-text signal is not emitted + 588395 Crash when opening a GtkBuilder file + 524066 Mandatory jpeg2000? + 527583 GtkAssistant should set buttons as default widget + 588694 Missing % in C code + 588484 Iconview DnD fails when Destination is empty + 583522 Trivial error in GtkBuilder migration documentation + 150951 collapsed save dialog needs to indicate filesystem... + +* Updated translations: + Brazilian Portuguese + Norwegian bokmål + Spanish + Traditional Chinese + + +Overview of Changes from GTK+ 2.17.3 to 2.17.4 +============================================== + +* GtkEntry now has model-view separation, with GtkEntryBuffer. + One intended use case for this is to support 'secure memory' + for password entries. + +* The print dialog can now optionally include the page setup + controls, avoiding the need for a separate page setup dialog + in many applications. + +* Coloring of visited links in GtkLabel can now be turned off, with + the ::track-visited-links property. + +* Support for clipmasks in gdk_draw_pixbuf now works, this will + introduce visual changes in code that uses clipmasks when drawing + pixbufs. However, since this never worked that is unlikely to happen. + Old code using gdk_pixbuf_render_threshold_alpha masks when rendering + pixbufs will now produce truncated results at the edges. + +* A number of regressions from the client-side window merge have + been fixed. + +* The directfb GDK backend has been fixed to build with csw. + +* Bugs fixed: + 569393 gtk calendar localization YM note is wrong + 587559 Popup closes immediately + 551409 Print dialog should include page size and orientation + 588115 gvim clipboard broken + +* Updated translations: + Dutch + Estonian + Spanish + Ukrainian + Vietnamese + + +Overview of Changes from GTK+ 2.17.2 to 2.17.3 +============================================== + +* GtkFileChooser: + - Shows the size column by default now + +* GtkStatusIcon: + - Has a title property, which can be used by ATs when they + read status icons + +* GtkInfoBar: + - The default theme now includes color definitions for infobars + - The ::use-tooltip-style style property has been removed + +* GtkMountOperation now supports interaction during unmount operations. + +* The client-side windows branch has been merged; GDK now maintains + its own window hierarchy client-side, and only uses X windows where + unavoidable. Some of the benefits of this change are + - Reduced flicker + - The ability to do transformed and animated rendering of widgets + - Easier embedding of GTK+ widgets e.g. into Clutter scene graphs + This is a fundamental change to the way GDK works, so watch out for + regressions. + +* Bugs fixed: + 586315 Crash in GTK+ 2.14 when calling gtk.FileChooser.list_shor... + 461944 pressing the volume icon in full screen shuts down the sound + 490724 iconview item's height would be changed event with same m... + 564063 regression: Left margin in popup menus + 582025 Accelerators fail for submenus + 585626 Setting widget tooltip hammers X11 server on any TCP/IP X... + 585802 Add API to make GtkStatusIcon accessible with a name + 585858 right-click Add-to-Booksmarks is sometimes greyed out + 586330 GtkButton ignores user_underline when an image is set + 318807 Offscreen windows and window redirection + 587716 GtkInfoBar broken on resize + 587485 GMountOperation::show-processes support + +* Updated translations + Brazilian Portuguese + Estonian + Hebrew + Spanish + Swedish + Vietnamese + + Overview of Changes from GTK+ 2.17.1 to 2.17.2 ============================================== diff --git a/README.in b/README.in index 3e2d7da727..84d6329e01 100644 --- a/README.in +++ b/README.in @@ -34,6 +34,21 @@ Release notes for 2.18 old custom_widget. Custom_widget does not get destroyed when the tooltip goes away. +* JPEG2000 support is no longer enabled by default. It must be + explicitly turned on, by passing --with-libjasper to configure. + +* GDK has been reworked to implement 'client-side windows'. This offers + exciting new possibilities, such as transformed, offscreen rendering, + but it breaks some long-standing assumptions that applications may + have about GDK windows. Setting the environment variable + GDK_NATIVE_WINDOWS makes GDK create a native X11 window for each + GDK window, which might make problematic applications work better. + +* GTK+ calls signal (SIGPIPE, SIG_IGN) during initialization, to ignore + SIGPIPE signals, since these are almost never wanted in graphical + applications. If you do need to handle SIGPIPE for some reason, reset + the handler after gtk_init(), but notice that other libraries (e.g. + libdbus or gvfs) might do similar things. Release notes for 2.16 ====================== @@ -427,8 +442,4 @@ report. Otherwise, enter a new bug report that describes the patch, and attach the patch to that bug report. -Bug reports containing patches should include the PATCH keyword in their -keyword fields. If the patch adds to or changes the GTK+ programming -interface, the API keyword should also be included. - -Patches should be in unified diff form. (The -u option to GNU diff.) +Patches should be in unified diff form. (The -up option to GNU diff.) diff --git a/README.win32 b/README.win32 index 9d731602fc..f7c8ca6307 100644 --- a/README.win32 +++ b/README.win32 @@ -1,117 +1,184 @@ -The Win32 backend in GTK+ is not as stable or correct as the X11 one. - -For prebuilt runtime and developer packages see -http://ftp.gnome.org/pub/gnome/binaries/win32/ - -Building GTK+ on Win32 -====================== - -First you obviously need developer packages for the compile-time -dependencies: Pango, atk, glib, gettext-runtime, libiconv, libpng, -zlib, libtiff at least. See -http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies . - -After installing the dependencies, there are two ways to build GTK+ -for win32. - -1) GNU tools, ./configure && make install ------------------------------------------ - -This requires you have mingw and MSYS. - -Use the configure script, and the resulting Makefiles (which use -libtool and gcc to do the compilation). I use this myself, but it can -be hard to setup correctly. - -The full script I run to build GTK+ 2.10 unpacked from a source -distribution is as below. This is from bulding GTK+ 2.10.9, slightly -edited to make it match this 2.11 development branch. Actually I don't -use any script like this to build the development branch, as I don't -distribute any binaries from development branches. - -MOD=gtk+ -VER=2.10.9 -THIS=$MOD-$VER -HEX=`echo $THIS | md5sum | cut -d' ' -f1` -TARGET=c:/devel/target/$HEX -DEPS="`/devel/src/tml/latest.sh glib atk cairo pango`" -sed -e 's/need_relink=yes/need_relink=no # no way --tml/' ltmain.temp && mv ltmain.temp ltmain.sh -usedev -usemsvs6 -MY_PKG_CONFIG_PATH="" -for D in $DEPS; do - PATH=/devel/dist/$D/bin:$PATH - MY_PKG_CONFIG_PATH=/devel/dist/$D/lib/pkgconfig:$MY_PKG_CONFIG_PATH -done -PKG_CONFIG_PATH=$MY_PKG_CONFIG_PATH:$PKG_CONFIG_PATH CC='gcc -mtune=pentium3 -mthreads' CPPFLAGS='-I/opt/gnu/include -I/opt/gnuwin32/include -I/opt/misc/include' LDFLAGS='-L/opt/gnu/lib -L/opt/gnuwin32/lib -L/opt/misc/lib -Wl,--enable-auto-image-base' LIBS=-lintl CFLAGS=-O2 ./configure --with-gdktarget=win32 --enable-debug=yes --disable-gtk-doc --disable-static --prefix=$TARGET && -libtoolcacheize && -unset MY_PKG_CONFIG_PATH && -PATH=/devel/target/$HEX/bin:.libs:$PATH make install && -(cd $TARGET/bin; strip --strip-unneeded *.dll *.exe) && -(cd $TARGET/lib/gtk-2.0/2.10.0/loaders; strip --strip-unneeded *.dll) && -(cd $TARGET/lib/gtk-2.0/2.10.0/immodules; strip --strip-unneeded *.dll) && -(cd $TARGET/lib/gtk-2.0/2.10.0/engines; strip --strip-unneeded *.dll) && -PATH=$TARGET/bin:$PATH gdk-pixbuf-query-loaders >$TARGET/etc/gtk-2.0/gdk-pixbuf.loaders && -grep -v -E 'Automatically generated|Created by|LoaderDir =' <$TARGET/etc/gtk-2.0/gdk-pixbuf.loaders >$TARGET/etc/gtk-2.0/gdk-pixbuf.loaders.temp && -mv $TARGET/etc/gtk-2.0/gdk-pixbuf.loaders.temp $TARGET/etc/gtk-2.0/gdk-pixbuf.loaders && -grep -v -E 'Automatically generated|Created by|ModulesPath =' <$TARGET/etc/gtk-2.0/gtk.immodules >$TARGET/etc/gtk-2.0/gtk.immodules.temp && -mv $TARGET/etc/gtk-2.0/gtk.immodules.temp $TARGET/etc/gtk-2.0/gtk.immodules && -./gtk-zip.sh && -(cd /devel/src/tml && zip /tmp/$MOD-dev-$VER.zip make/$THIS.make) && -manifestify /tmp/$MOD*-$VER.zip - -You should not just copy the above blindly. There are some things in -the script that are very specific to *my* build setup on *my* current -machine. For instance the "latest.sh" script, the "usedev" and -"usemsvs6" shell functions, the /devel/dist folder. The above script -is really just meant for reference, to give an idea. You really need -to understand what things like PKG_CONFIG_PATH are and set them up -properly after installing the dependencies before building GTK+. - -As you see above, after running configure, one can just say "make -install", like on Unix. A post-build fix is needed, running -gdk-pixbuf-query-loaders once more to get a correct gdk-pixbuf.loaders -file. - -2) Microsoft's tools --------------------- - -Use the Microsoft compiler, cl and Make, nmake. Say nmake -f -makefile.msc in gdk and gtk. Be prepared to manually edit various -makefile.msc files, and the makefile snippets in build/win32. - -Alternative 1 also generates Microsoft import libraries (.lib), if you -have lib.exe available. It might also work for cross-compilation from -Unix. - -I use method 1 myself. Hans Breuer has been taking care of the MSVC -makefiles. At times, we disagree a bit about various issues, and for -instance the makefile.msc files might not produce identically named -DLLs and import libraries as the "autoconfiscated" makefiles and -libtool do. If this bothers you, you will have to fix the makefiles. - -Using GTK+ on Win32 -=================== - -To use GTK+ on Win32, you also need either one of the above mentioned -compilers. Other compilers might work, but don't count on it. Look for -prebuilt developer packages (DLLs, import libraries, headers) on the -above website. - -Multi-threaded use of GTK+ on Win32 -=================================== - -Multi-threaded GTK+ programs might work on Windows in special simple -cases, but not in general. Sorry. If you have all GTK+ and GDK calls -in the same thread, it might work. Otherwise, probably not at -all. Possible ways to fix this are being investigated. - -Wintab -====== - -The tablet support uses the Wintab API. The Wintab development kit is -no longer required. The wintab.h header file is bundled with GTK+ -sources. Unfortunately it seems that only Wacom tablets come with -support for the Wintab API nowadays. - ---Tor Lillqvist , +The Win32 backend in GTK+ is not as stable or correct as the X11 one. + +For prebuilt runtime and developer packages see +http://ftp.gnome.org/pub/gnome/binaries/win32/ + +Building GTK+ on Win32 +====================== + +First you obviously need developer packages for the compile-time +dependencies: Pango, atk, glib, gettext-runtime, libiconv, libpng, +zlib, libtiff at least. See +http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies . + +After installing the dependencies, there are two ways to build GTK+ +for win32. + +1) GNU tools, ./configure && make install +----------------------------------------- + +This requires you have mingw and MSYS. + +Use the configure script, and the resulting Makefiles (which use +libtool and gcc to do the compilation). I use this myself, but it can +be hard to setup correctly. + +The full script I run to build GTK+ 2.16 unpacked from a source +distribution is as below. This is from bulding GTK+ 2.16.5. I don't +use any script like this to build the development branch, as I don't +distribute any binaries from development branches. + +# This is a shell script that calls functions and scripts from +# tml@iki.fi's personal work envronment. It is not expected to be +# usable unmodified by others, and is included only for reference. + +MOD=gtk+ +VER=2.16.5 +REV=1 +ARCH=win32 + +THIS=${MOD}_${VER}-${REV}_${ARCH} + +RUNZIP=${MOD}_${VER}-${REV}_${ARCH}.zip +DEVZIP=${MOD}-dev_${VER}-${REV}_${ARCH}.zip + +HEX=`echo $THIS | md5sum | cut -d' ' -f1` +TARGET=c:/devel/target/$HEX + +usedev +usemsvs6 + +( + +set -x + +DEPS=`latest --arch=${ARCH} glib atk cairo pango libpng zlib libtiff jpeg` +PROXY_LIBINTL=`latest --arch=${ARCH} proxy-libintl` + +PKG_CONFIG_PATH= +for D in $DEPS; do + PATH=/devel/dist/${ARCH}/$D/bin:$PATH + [ -d /devel/dist/${ARCH}/$D/lib/pkgconfig ] && PKG_CONFIG_PATH=/devel/dist/${ARCH}/$D/lib/pkgconfig:$PKG_CONFIG_PATH +done + +LIBPNG=`latest --arch=${ARCH} libpng` +ZLIB=`latest --arch=${ARCH} zlib` +LIBTIFF=`latest --arch=${ARCH} libtiff` +JPEG=`latest --arch=${ARCH} jpeg` + +patch -p0 <<'EOF' +EOF + +lt_cv_deplibs_check_method='pass_all' \ +CC='gcc -mtune=pentium3 -mthreads' \ +CPPFLAGS="-I/devel/dist/${ARCH}/${LIBPNG}/include \ +-I/devel/dist/${ARCH}/${ZLIB}/include \ +-I/devel/dist/${ARCH}/${LIBTIFF}/include \ +-I/devel/dist/${ARCH}/${JPEG}/include \ +-I/devel/dist/${ARCH}/${PROXY_LIBINTL}/include" \ +LDFLAGS="-L/devel/dist/${ARCH}/${LIBPNG}/lib \ +-L/devel/dist/${ARCH}/${ZLIB}/lib \ +-L/devel/dist/${ARCH}/${LIBTIFF}/lib \ +-L/devel/dist/${ARCH}/${JPEG}/lib \ +-L/devel/dist/${ARCH}/${PROXY_LIBINTL}/lib -Wl,--exclude-libs=libintl.a \ +-Wl,--enable-auto-image-base" \ +LIBS=-lintl \ +CFLAGS=-O2 \ +./configure \ +--with-gdktarget=win32 \ +--disable-gdiplus \ +--with-included-immodules \ +--without-libjasper \ +--enable-debug=yes \ +--enable-explicit-deps=no \ +--disable-gtk-doc \ +--disable-static \ +--prefix=$TARGET && + +libtoolcacheize && +rm gtk/gtk.def && +(PATH="$PWD/gdk-pixbuf/.libs:/devel/target/$HEX/bin:$PATH" make -j3 install || (rm .libtool-cache* && PATH="/devel/target/$HEX/bin:$PATH" make -j3 install)) && + +PATH="/devel/target/$HEX/bin:$PATH" gdk-pixbuf-query-loaders >/devel/target/$HEX/etc/gtk-2.0/gdk-pixbuf.loaders && + +grep -v -E 'Automatically generated|Created by|LoaderDir =' <$TARGET/etc/gtk-2.0/gdk-pixbuf.loaders >$TARGET/etc/gtk-2.0/gdk-pixbuf.loaders.temp && + mv $TARGET/etc/gtk-2.0/gdk-pixbuf.loaders.temp $TARGET/etc/gtk-2.0/gdk-pixbuf.loaders && +grep -v -E 'Automatically generated|Created by|ModulesPath =' <$TARGET/etc/gtk-2.0/gtk.immodules >$TARGET/etc/gtk-2.0/gtk.immodules.temp && + mv $TARGET/etc/gtk-2.0/gtk.immodules.temp $TARGET/etc/gtk-2.0/gtk.immodules && + +./gtk-zip.sh && + +mv /tmp/${MOD}-${VER}.zip /tmp/$RUNZIP && +mv /tmp/${MOD}-dev-${VER}.zip /tmp/$DEVZIP + +) 2>&1 | tee /devel/src/tml/packaging/$THIS.log + +(cd /devel && zip /tmp/$DEVZIP src/tml/packaging/$THIS.{sh,log}) && +manifestify /tmp/$RUNZIP /tmp/$DEVZIP + +You should not just copy the above blindly. There are some things in +the script that are very specific to *my* build setup on *my* current +machine. For instance the "latest" command, the "usedev" and +"usemsvs6" shell functions, the /devel/dist folder. The above script +is really just meant for reference, to give an idea. You really need +to understand what things like PKG_CONFIG_PATH are and set them up +properly after installing the dependencies before building GTK+. + +As you see above, after running configure, one can just say "make +install", like on Unix. A post-build fix is needed, running +gdk-pixbuf-query-loaders once more to get a correct gdk-pixbuf.loaders +file. + +For a 64-bit build you need to remove the gtk/gtk.def file and let it +be regenerated by the makefilery. This is because the 64-bit GTK dll +has a slightly different list of exported function names. This is on +purpose and not a bug. The API is the same at the source level, and +the same #defines of some function names to actually have a _utf8 +suffix is used (just to keep the header simpler). But the +corresponding non-suffixed function to maintain ABI stability are not +needed in the 64-bit case (because there are no older EXEs around that +would require such for ABI stability). + + +2) Microsoft's tools +-------------------- + +Use the Microsoft compiler, cl and Make, nmake. Say nmake -f +makefile.msc in gdk and gtk. Be prepared to manually edit various +makefile.msc files, and the makefile snippets in build/win32. + +Alternative 1 also generates Microsoft import libraries (.lib), if you +have lib.exe available. It might also work for cross-compilation from +Unix. + +I use method 1 myself. Hans Breuer has been taking care of the MSVC +makefiles. At times, we disagree a bit about various issues, and for +instance the makefile.msc files might not produce identically named +DLLs and import libraries as the "autoconfiscated" makefiles and +libtool do. If this bothers you, you will have to fix the makefiles. + +Using GTK+ on Win32 +=================== + +To use GTK+ on Win32, you also need either one of the above mentioned +compilers. Other compilers might work, but don't count on it. Look for +prebuilt developer packages (DLLs, import libraries, headers) on the +above website. + +Multi-threaded use of GTK+ on Win32 +=================================== + +Multi-threaded GTK+ programs might work on Windows in special simple +cases, but not in general. Sorry. If you have all GTK+ and GDK calls +in the same thread, it might work. Otherwise, probably not at +all. Possible ways to fix this are being investigated. + +Wintab +====== + +The tablet support uses the Wintab API. The Wintab development kit is +no longer required. The wintab.h header file is bundled with GTK+ +sources. Unfortunately it seems that only Wacom tablets come with +support for the Wintab API nowadays. + +--Tor Lillqvist , diff --git a/autogen.sh b/autogen.sh index d3fb066d3e..19d2bdc81a 100755 --- a/autogen.sh +++ b/autogen.sh @@ -14,7 +14,10 @@ DIE=0 have_libtool=false if libtoolize --version < /dev/null > /dev/null 2>&1 ; then - libtool_version=`libtoolize --version | sed 's/^[^0-9]*\([0-9.][0-9.]*\).*/\1/'` + libtool_version=`libtoolize --version | + head -1 | + sed -e 's/^\(.*\)([^)]*)\(.*\)$/\1\2/g' \ + -e 's/^[^0-9]*\([0-9.][0-9.]*\).*/\1/'` case $libtool_version in 1.4*|1.5*|2.2*) have_libtool=true @@ -45,16 +48,24 @@ fi DIE=1 } -if automake-1.7 --version < /dev/null > /dev/null 2>&1 ; then +if automake-1.11 --version < /dev/null > /dev/null 2>&1 ; then + AUTOMAKE=automake-1.11 + ACLOCAL=aclocal-1.11 +else if automake-1.10 --version < /dev/null > /dev/null 2>&1 ; then + AUTOMAKE=automake-1.10 + ACLOCAL=aclocal-1.10 +else if automake-1.7 --version < /dev/null > /dev/null 2>&1 ; then AUTOMAKE=automake-1.7 ACLOCAL=aclocal-1.7 else echo - echo "You must have automake 1.7.x installed to compile $PROJECT." + echo "You must have automake 1.7.x, 1,10.x or 1.11.x installed to compile $PROJECT." echo "Install the appropriate package for your distribution," echo "or get the source tarball at http://ftp.gnu.org/gnu/automake/" DIE=1 fi +fi +fi if test "$DIE" -eq 1; then exit 1 diff --git a/config.h.win32.in b/config.h.win32.in index 4b0bb0f401..c3eea4ef79 100644 --- a/config.h.win32.in +++ b/config.h.win32.in @@ -269,7 +269,11 @@ /* #undef USE_MEDIALIB25 */ /* Define to 1 if XXM is available and should be used */ -#define USE_MMX 1 +#ifndef _MSC_VER +# define USE_MMX 1 +#else +# undef USE_MMX +#endif /* Define to 1 if no XInput should be used */ /* #undef XINPUT_NONE */ diff --git a/configure.in b/configure.in index 7249d78962..5edd8794f2 100644 --- a/configure.in +++ b/configure.in @@ -11,9 +11,9 @@ AC_PREREQ(2.54) # set GTK_BINARY_AGE and GTK_INTERFACE_AGE to 0. m4_define([gtk_major_version], [2]) -m4_define([gtk_minor_version], [17]) -m4_define([gtk_micro_version], [3]) -m4_define([gtk_interface_age], [0]) +m4_define([gtk_minor_version], [18]) +m4_define([gtk_micro_version], [2]) +m4_define([gtk_interface_age], [2]) m4_define([gtk_binary_age], [m4_eval(100 * gtk_minor_version + gtk_micro_version)]) m4_define([gtk_version], @@ -49,6 +49,11 @@ cflags_set=${CFLAGS+set} AM_INIT_AUTOMAKE(no-define) AM_CONFIG_HEADER(config.h) +# Support silent build rules, requires at least automake-1.11. Enable +# by either passing --enable-silent-rules to configure or passing V=0 +# to make +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([no])]) + # # For each of the libraries we build, we define the following @@ -302,6 +307,7 @@ AM_SANITY_CHECK # Checks for programs. AC_ISC_POSIX AM_PROG_CC_STDC +AM_PROG_CC_C_O AC_PROG_INSTALL AC_PROG_MAKE_SET @@ -825,12 +831,13 @@ AC_ARG_WITH(libtiff, [AC_HELP_STRING([--without-libtiff], [disable TIFF loader for gdk-pixbuf])]) AC_ARG_WITH(libjasper, - [AC_HELP_STRING([--without-libjasper], - [disable JPEG2000 loader for gdk-pixbuf])]) + [AC_HELP_STRING([--with-libjasper], + [enable JPEG2000 loader for gdk-pixbuf])]) AC_ARG_ENABLE(gdiplus, - [AC_HELP_STRING([--disable-gdiplus], - [disable GDI+ loaders for gdk-pixbuf])]) + [AC_HELP_STRING([--enable-gdiplus], + [enble GDI+ loaders for gdk-pixbuf (currently known to be broken)])],, + [enable_gdiplus=no]) AM_CONDITIONAL(BUILD_GDIPLUS_LOADERS, [ test x$os_win32 = xyes && test x$enable_gdiplus != xno ]) @@ -940,11 +947,11 @@ dnl Test for libpng fi dnl Test for libjasper - if test x$with_libjasper != xno && test -z "$LIBJASPER"; then + if test x$with_libjasper = xyes && test -z "$LIBJASPER"; then AC_CHECK_LIB(jasper, jas_init, LIBJASPER=-ljasper, [], -ljpeg) fi - if test x$with_libjasper != xno && test -z "$LIBJASPER"; then + if test x$with_libjasper = xyes && test -z "$LIBJASPER"; then AC_MSG_ERROR([ *** Checks for JPEG2000 loader failed. You can build without it by passing *** --without-libjasper to configure]) @@ -1317,7 +1324,6 @@ GDK_PIXBUF_XLIB_PACKAGES= GDK_PIXBUF_XLIB_EXTRA_CFLAGS= GDK_PIXBUF_XLIB_EXTRA_LIBS= -X_PACKAGES=fontconfig GDK_EXTRA_LIBS="$GDK_WLIBS" GDK_EXTRA_CFLAGS= @@ -1326,6 +1332,8 @@ GTK_DEP_PACKAGES_FOR_X= GTK_DEP_LIBS_FOR_X= if test "x$gdktarget" = "xx11"; then + X_PACKAGES=fontconfig + # # We use fontconfig very peripherally when decoding the default # settings. @@ -1626,6 +1634,8 @@ if test "x$gdktarget" = "xx11"; then AM_CONDITIONAL(USE_X11, true) else + XPACKAGES= + AM_CONDITIONAL(XINPUT_XFREE, false) AM_CONDITIONAL(USE_X11, false) AM_CONDITIONAL(HAVE_X11R6, false) @@ -1832,10 +1842,19 @@ AC_ARG_ENABLE(cups, [disable cups print backend])],, [enable_cups=auto]) -if test "x$enable_cups" = "xauto" -then +if test "x$enable_cups" = "xno"; then + AM_CONDITIONAL(HAVE_CUPS, false) +else AC_PATH_PROG(CUPS_CONFIG, cups-config, no) - if test "x$CUPS_CONFIG" != "xno"; then + if test "x$CUPS_CONFIG" = "xno"; then + if test "x$enable_cups" = "xauto"; then + AM_CONDITIONAL(HAVE_CUPS, false) + else + AC_MSG_ERROR([ +*** cups not found. +]) + fi + else CUPS_CFLAGS=`$CUPS_CONFIG --cflags | sed 's/-O[0-9]*//' | sed 's/-m[^\t]*//g'` CUPS_LIBS=`$CUPS_CONFIG --libs` @@ -1855,26 +1874,24 @@ then AC_SUBST(CUPS_LIBS) AC_CHECK_HEADER(cups/cups.h,,AC_MSG_ERROR([[*** Sorry, cups-config present but cups/cups.h missing.]])) + + AM_CONDITIONAL(HAVE_CUPS, true) + + gtk_save_cflags="$CFLAGS" + CFLAGS="$CUPS_CFLAGS" + AC_TRY_COMPILE([#include ], + [http_t http; char *s = http.authstring;], + [AC_DEFINE(HAVE_HTTP_AUTHSTRING, [], + [Define if cups http_t authstring field is accessible])],) + CFLAGS="$gtk_save_cflags" + + AC_SUBST(HAVE_HTTP_AUTHSTRING) + + gtk_save_libs="$LIBS" + LIBS="$CUPS_LIBS" + AC_CHECK_FUNCS(httpGetAuthString) + LIBS="$gtk_save_libs" fi - AM_CONDITIONAL(HAVE_CUPS, test "x$CUPS_CONFIG" != "xno") - - gtk_save_cflags="$CFLAGS" - CFLAGS="$CUPS_CFLAGS" - AC_TRY_COMPILE([#include ], - [http_t http; char *s = http.authstring;], - [AC_DEFINE(HAVE_HTTP_AUTHSTRING, [], - [Define if cups http_t authstring field is accessible])],) - CFLAGS="$gtk_save_cflags" - - AC_SUBST(HAVE_HTTP_AUTHSTRING) - - gtk_save_libs="$LIBS" - LIBS="$CUPS_LIBS" - AC_CHECK_FUNCS(httpGetAuthString) - LIBS="$gtk_save_libs" - -else - AM_CONDITIONAL(HAVE_CUPS, false) fi # Checks to see if we should compile with PAPI backend for GTK+ @@ -1885,23 +1902,27 @@ AC_ARG_ENABLE(papi, [disable papi print backend])],, [enable_papi=auto]) -if test "x$enable_papi" = "xauto" -then +if test "x$enable_papi" = "xno"; then + AM_CONDITIONAL(HAVE_PAPI, false) +else AC_MSG_CHECKING(libpapi) AC_CHECK_LIB(papi, papiServiceCreate, have_papi=yes, have_papi=no) if test $have_papi = yes; then AC_DEFINE([HAVE_PAPI], [], [Define to 1 if libpapi available]) fi AM_CONDITIONAL(HAVE_PAPI, test $have_papi = yes) -else - AM_CONDITIONAL(HAVE_PAPI, false) + if test "x$enable_papi" = "xyes" -a "x$have_papi" = "xno"; then + AC_MSG_ERROR([ +*** papi not found. +]) + fi fi -AM_CONDITIONAL(HAVE_PAPI_CUPS, test $have_papi = yes && test "x$CUPS_CONFIG" != "xno") +AM_CONDITIONAL(HAVE_PAPI_CUPS, test "x$have_papi" = "xyes" -a "x$CUPS_CONFIG" != "xno") gtk_save_cppflags="$CPPFLAGS" -CPPFLAGS="$CPPFLAGS $GTK_DEP_CFLAGS" - +CPPFLAGS="$CPPFLAGS $GTK_DEP_CFLAGS $GDK_DEP_CFLAGS" + AC_CHECK_HEADER(cairo-pdf.h,,AC_MSG_ERROR([ *** Can't find cairo-pdf.h. You must build Cairo with the pdf *** backend enabled.])) diff --git a/demos/gtk-demo/Makefile.am b/demos/gtk-demo/Makefile.am index 23eed00eec..b2d856856f 100644 --- a/demos/gtk-demo/Makefile.am +++ b/demos/gtk-demo/Makefile.am @@ -17,6 +17,7 @@ demos = \ dialog.c \ drawingarea.c \ editable_cells.c \ + entry_buffer.c \ entry_completion.c \ expander.c \ hypertext.c \ @@ -27,6 +28,8 @@ demos = \ links.c \ list_store.c \ menus.c \ + offscreen_window.c \ + offscreen_window2.c \ panes.c \ pickers.c \ pixbufs.c \ diff --git a/demos/gtk-demo/clipboard.c b/demos/gtk-demo/clipboard.c index 8e6c2809d4..5559c5e78d 100644 --- a/demos/gtk-demo/clipboard.c +++ b/demos/gtk-demo/clipboard.c @@ -203,6 +203,10 @@ do_clipboard (GtkWidget *do_widget) GtkClipboard *clipboard; window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_screen (GTK_WINDOW (window), + gtk_widget_get_screen (do_widget)); + gtk_window_set_title (GTK_WINDOW (window), "Clipboard demo"); + g_signal_connect (window, "destroy", G_CALLBACK (gtk_widget_destroyed), &window); diff --git a/demos/gtk-demo/entry_buffer.c b/demos/gtk-demo/entry_buffer.c new file mode 100644 index 0000000000..2be770e3bf --- /dev/null +++ b/demos/gtk-demo/entry_buffer.c @@ -0,0 +1,65 @@ +/* Entry/Entry Buffer + * + * GtkEntryBuffer provides the text content in a GtkEntry. + * + */ + +#include + +static GtkWidget *window = NULL; + +GtkWidget * +do_entry_buffer (GtkWidget *do_widget) +{ + GtkWidget *vbox; + GtkWidget *label; + GtkWidget *entry; + GtkEntryBuffer *buffer; + + if (!window) + { + window = gtk_dialog_new_with_buttons ("GtkEntryBuffer", + GTK_WINDOW (do_widget), + 0, + GTK_STOCK_CLOSE, + GTK_RESPONSE_NONE, + NULL); + gtk_window_set_resizable (GTK_WINDOW (window), FALSE); + + g_signal_connect (window, "response", + G_CALLBACK (gtk_widget_destroy), NULL); + g_signal_connect (window, "destroy", + G_CALLBACK (gtk_widget_destroyed), &window); + + vbox = gtk_vbox_new (FALSE, 5); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), vbox, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (vbox), 5); + + label = gtk_label_new (NULL); + gtk_label_set_markup (GTK_LABEL (label), "Entries share a buffer. Typing in one is reflected in the other."); + gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); + + /* Create a buffer */ + buffer = gtk_entry_buffer_new (NULL, 0); + + /* Create our first entry */ + entry = gtk_entry_new_with_buffer (buffer); + gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0); + + /* Create the second entry */ + entry = gtk_entry_new_with_buffer (buffer); + gtk_entry_set_visibility (GTK_ENTRY (entry), FALSE); + gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0); + + g_object_unref (buffer); + } + + if (!GTK_WIDGET_VISIBLE (window)) + gtk_widget_show_all (window); + else + gtk_widget_destroy (window); + + return window; +} + + diff --git a/demos/gtk-demo/links.c b/demos/gtk-demo/links.c index c506144c87..569cd91231 100644 --- a/demos/gtk-demo/links.c +++ b/demos/gtk-demo/links.c @@ -43,11 +43,11 @@ activate_link (GtkWidget *label, return FALSE; } +static GtkWidget *window = NULL; + GtkWidget * do_links (GtkWidget *do_widget) { - static GtkWidget *window = NULL; - GtkWidget *box; GtkWidget *label; if (!window) @@ -55,11 +55,10 @@ do_links (GtkWidget *do_widget) window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_screen (GTK_WINDOW (window), gtk_widget_get_screen (do_widget)); + gtk_window_set_title (GTK_WINDOW (window), "Links"); gtk_container_set_border_width (GTK_CONTAINER (window), 12); g_signal_connect (window, "destroy", - G_CALLBACK(gtk_widget_destroyed), &window); - g_signal_connect (window, "delete-event", - G_CALLBACK (gtk_true), NULL); + G_CALLBACK (gtk_widget_destroyed), &window); label = gtk_label_new ("Some text may be marked up\n" diff --git a/demos/gtk-demo/menus.c b/demos/gtk-demo/menus.c index ddb4cf462f..2e6fe2951c 100644 --- a/demos/gtk-demo/menus.c +++ b/demos/gtk-demo/menus.c @@ -2,10 +2,10 @@ * * There are several widgets involved in displaying menus. The * GtkMenuBar widget is a menu bar, which normally appears horizontally - * at the top of an application, but can also be layed out vertically. - * The GtkMenu widget is the actual menu that pops up. Both GtkMenuBar - * and GtkMenu are subclasses of GtkMenuShell; a GtkMenuShell contains - * menu items (GtkMenuItem). Each menu item contains text and/or images + * at the top of an application, but can also be layed out vertically. + * The GtkMenu widget is the actual menu that pops up. Both GtkMenuBar + * and GtkMenu are subclasses of GtkMenuShell; a GtkMenuShell contains + * menu items (GtkMenuItem). Each menu item contains text and/or images * and can be selected by the user. * * There are several kinds of menu item, including plain GtkMenuItem, @@ -22,7 +22,6 @@ * GtkUIManager provides a higher-level interface for creating menu bars * and menus; while you can construct menus manually, most people don't * do that. There's a separate demo for GtkUIManager. - * */ #include @@ -118,37 +117,35 @@ change_orientation (GtkWidget *button, } } +static GtkWidget *window = NULL; + GtkWidget * do_menus (GtkWidget *do_widget) { - static GtkWidget *window = NULL; GtkWidget *box; GtkWidget *box1; GtkWidget *box2; GtkWidget *button; - + if (!window) { GtkWidget *menubar; GtkWidget *menu; GtkWidget *menuitem; GtkAccelGroup *accel_group; - + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_screen (GTK_WINDOW (window), gtk_widget_get_screen (do_widget)); + gtk_window_set_title (GTK_WINDOW (window), "Menus"); g_signal_connect (window, "destroy", G_CALLBACK(gtk_widget_destroyed), &window); - g_signal_connect (window, "delete-event", - G_CALLBACK (gtk_true), NULL); - + accel_group = gtk_accel_group_new (); gtk_window_add_accel_group (GTK_WINDOW (window), accel_group); - gtk_window_set_title (GTK_WINDOW (window), "menus"); gtk_container_set_border_width (GTK_CONTAINER (window), 0); - - + box = gtk_hbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (window), box); gtk_widget_show (box); @@ -156,18 +153,18 @@ do_menus (GtkWidget *do_widget) box1 = gtk_vbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (box), box1); gtk_widget_show (box1); - + menubar = gtk_menu_bar_new (); gtk_box_pack_start (GTK_BOX (box1), menubar, FALSE, TRUE, 0); gtk_widget_show (menubar); - + menu = create_menu (2, TRUE); - + menuitem = gtk_menu_item_new_with_label ("test\nline2"); gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu); gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem); gtk_widget_show (menuitem); - + menuitem = gtk_menu_item_new_with_label ("foo"); gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (3, TRUE)); gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem); @@ -178,7 +175,7 @@ do_menus (GtkWidget *do_widget) gtk_menu_item_set_right_justified (GTK_MENU_ITEM (menuitem), TRUE); gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem); gtk_widget_show (menuitem); - + box2 = gtk_vbox_new (FALSE, 10); gtk_container_set_border_width (GTK_CONTAINER (box2), 10); gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0); diff --git a/demos/gtk-demo/offscreen_window.c b/demos/gtk-demo/offscreen_window.c new file mode 100644 index 0000000000..32c9c8c095 --- /dev/null +++ b/demos/gtk-demo/offscreen_window.c @@ -0,0 +1,579 @@ +/* Offscreen windows/Rotated button + * + * Offscreen windows can be used to transform parts of a widget + * hierarchy. Note that the rotated button is fully functional. + */ +#include +#include + +#define GTK_TYPE_ROTATED_BIN (gtk_rotated_bin_get_type ()) +#define GTK_ROTATED_BIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_ROTATED_BIN, GtkRotatedBin)) +#define GTK_ROTATED_BIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_ROTATED_BIN, GtkRotatedBinClass)) +#define GTK_IS_ROTATED_BIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_ROTATED_BIN)) +#define GTK_IS_ROTATED_BIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_ROTATED_BIN)) +#define GTK_ROTATED_BIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_ROTATED_BIN, GtkRotatedBinClass)) + +typedef struct _GtkRotatedBin GtkRotatedBin; +typedef struct _GtkRotatedBinClass GtkRotatedBinClass; + +struct _GtkRotatedBin +{ + GtkContainer container; + + GtkWidget *child; + GdkWindow *offscreen_window; + gdouble angle; +}; + +struct _GtkRotatedBinClass +{ + GtkContainerClass parent_class; +}; + +GType gtk_rotated_bin_get_type (void) G_GNUC_CONST; +GtkWidget* gtk_rotated_bin_new (void); +void gtk_rotated_bin_set_angle (GtkRotatedBin *bin, + gdouble angle); + +/*** implementation ***/ + +static void gtk_rotated_bin_realize (GtkWidget *widget); +static void gtk_rotated_bin_unrealize (GtkWidget *widget); +static void gtk_rotated_bin_size_request (GtkWidget *widget, + GtkRequisition *requisition); +static void gtk_rotated_bin_size_allocate (GtkWidget *widget, + GtkAllocation *allocation); +static gboolean gtk_rotated_bin_damage (GtkWidget *widget, + GdkEventExpose *event); +static gboolean gtk_rotated_bin_expose (GtkWidget *widget, + GdkEventExpose *offscreen); + +static void gtk_rotated_bin_add (GtkContainer *container, + GtkWidget *child); +static void gtk_rotated_bin_remove (GtkContainer *container, + GtkWidget *widget); +static void gtk_rotated_bin_forall (GtkContainer *container, + gboolean include_internals, + GtkCallback callback, + gpointer callback_data); +static GType gtk_rotated_bin_child_type (GtkContainer *container); + +G_DEFINE_TYPE (GtkRotatedBin, gtk_rotated_bin, GTK_TYPE_CONTAINER); + +static void +to_child (GtkRotatedBin *bin, + double widget_x, + double widget_y, + double *x_out, + double *y_out) +{ + GtkAllocation child_area; + double x, y, xr, yr; + double c, s; + double w, h; + + s = sin (bin->angle); + c = cos (bin->angle); + child_area = bin->child->allocation; + + w = c * child_area.width + s * child_area.height; + h = s * child_area.width + c * child_area.height; + + x = widget_x; + y = widget_y; + + x -= (w - child_area.width) / 2; + y -= (h - child_area.height) / 2; + + x -= child_area.width / 2; + y -= child_area.height / 2; + + xr = x * c + y * s; + yr = y * c - x * s; + x = xr; + y = yr; + + x += child_area.width / 2; + y += child_area.height / 2; + + *x_out = x; + *y_out = y; +} + +static void +to_parent (GtkRotatedBin *bin, + double offscreen_x, + double offscreen_y, + double *x_out, + double *y_out) +{ + GtkAllocation child_area; + double x, y, xr, yr; + double c, s; + double w, h; + + s = sin (bin->angle); + c = cos (bin->angle); + child_area = bin->child->allocation; + + w = c * child_area.width + s * child_area.height; + h = s * child_area.width + c * child_area.height; + + x = offscreen_x; + y = offscreen_y; + + x -= child_area.width / 2; + y -= child_area.height / 2; + + xr = x * c - y * s; + yr = x * s + y * c; + x = xr; + y = yr; + + x += child_area.width / 2; + y += child_area.height / 2; + + x -= (w - child_area.width) / 2; + y -= (h - child_area.height) / 2; + + *x_out = x; + *y_out = y; +} + +static void +gtk_rotated_bin_class_init (GtkRotatedBinClass *klass) +{ + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass); + + widget_class->realize = gtk_rotated_bin_realize; + widget_class->unrealize = gtk_rotated_bin_unrealize; + widget_class->size_request = gtk_rotated_bin_size_request; + widget_class->size_allocate = gtk_rotated_bin_size_allocate; + widget_class->expose_event = gtk_rotated_bin_expose; + + g_signal_override_class_closure (g_signal_lookup ("damage-event", GTK_TYPE_WIDGET), + GTK_TYPE_ROTATED_BIN, + g_cclosure_new (G_CALLBACK (gtk_rotated_bin_damage), + NULL, NULL)); + + container_class->add = gtk_rotated_bin_add; + container_class->remove = gtk_rotated_bin_remove; + container_class->forall = gtk_rotated_bin_forall; + container_class->child_type = gtk_rotated_bin_child_type; +} + +static void +gtk_rotated_bin_init (GtkRotatedBin *bin) +{ + GTK_WIDGET_UNSET_FLAGS (bin, GTK_NO_WINDOW); +} + +GtkWidget * +gtk_rotated_bin_new (void) +{ + return g_object_new (GTK_TYPE_ROTATED_BIN, NULL); +} + +static GdkWindow * +pick_offscreen_child (GdkWindow *offscreen_window, + double widget_x, + double widget_y, + GtkRotatedBin *bin) +{ + GtkAllocation child_area; + double x, y; + + if (bin->child && GTK_WIDGET_VISIBLE (bin->child)) + { + to_child (bin, widget_x, widget_y, &x, &y); + + child_area = bin->child->allocation; + + if (x >= 0 && x < child_area.width && + y >= 0 && y < child_area.height) + return bin->offscreen_window; + } + + return NULL; +} + +static void +offscreen_window_to_parent (GdkWindow *offscreen_window, + double offscreen_x, + double offscreen_y, + double *parent_x, + double *parent_y, + GtkRotatedBin *bin) +{ + to_parent (bin, offscreen_x, offscreen_y, parent_x, parent_y); +} + +static void +offscreen_window_from_parent (GdkWindow *window, + double parent_x, + double parent_y, + double *offscreen_x, + double *offscreen_y, + GtkRotatedBin *bin) +{ + to_child (bin, parent_x, parent_y, offscreen_x, offscreen_y); +} + +static void +gtk_rotated_bin_realize (GtkWidget *widget) +{ + GtkRotatedBin *bin = GTK_ROTATED_BIN (widget); + GdkWindowAttr attributes; + gint attributes_mask; + gint border_width; + GtkRequisition child_requisition; + + GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); + + border_width = GTK_CONTAINER (widget)->border_width; + + attributes.x = widget->allocation.x + border_width; + attributes.y = widget->allocation.y + border_width; + attributes.width = widget->allocation.width - 2 * border_width; + attributes.height = widget->allocation.height - 2 * border_width; + attributes.window_type = GDK_WINDOW_CHILD; + attributes.event_mask = gtk_widget_get_events (widget) + | GDK_EXPOSURE_MASK + | GDK_POINTER_MOTION_MASK + | GDK_BUTTON_PRESS_MASK + | GDK_BUTTON_RELEASE_MASK + | GDK_SCROLL_MASK + | GDK_ENTER_NOTIFY_MASK + | GDK_LEAVE_NOTIFY_MASK; + + attributes.visual = gtk_widget_get_visual (widget); + attributes.colormap = gtk_widget_get_colormap (widget); + attributes.wclass = GDK_INPUT_OUTPUT; + + attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; + + widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), + &attributes, attributes_mask); + gdk_window_set_user_data (widget->window, widget); + g_signal_connect (widget->window, "pick-embedded-child", + G_CALLBACK (pick_offscreen_child), bin); + + attributes.window_type = GDK_WINDOW_OFFSCREEN; + + child_requisition.width = child_requisition.height = 0; + if (bin->child && GTK_WIDGET_VISIBLE (bin->child)) + { + attributes.width = bin->child->allocation.width; + attributes.height = bin->child->allocation.height; + } + bin->offscreen_window = gdk_window_new (gtk_widget_get_root_window (widget), + &attributes, attributes_mask); + gdk_window_set_user_data (bin->offscreen_window, widget); + if (bin->child) + gtk_widget_set_parent_window (bin->child, bin->offscreen_window); + gdk_offscreen_window_set_embedder (bin->offscreen_window, widget->window); + g_signal_connect (bin->offscreen_window, "to-embedder", + G_CALLBACK (offscreen_window_to_parent), bin); + g_signal_connect (bin->offscreen_window, "from-embedder", + G_CALLBACK (offscreen_window_from_parent), bin); + + widget->style = gtk_style_attach (widget->style, widget->window); + + gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL); + gtk_style_set_background (widget->style, bin->offscreen_window, GTK_STATE_NORMAL); + gdk_window_show (bin->offscreen_window); +} + +static void +gtk_rotated_bin_unrealize (GtkWidget *widget) +{ + GtkRotatedBin *bin = GTK_ROTATED_BIN (widget); + + gdk_window_set_user_data (bin->offscreen_window, NULL); + gdk_window_destroy (bin->offscreen_window); + bin->offscreen_window = NULL; + + GTK_WIDGET_CLASS (gtk_rotated_bin_parent_class)->unrealize (widget); +} + +static GType +gtk_rotated_bin_child_type (GtkContainer *container) +{ + GtkRotatedBin *bin = GTK_ROTATED_BIN (container); + + if (bin->child) + return G_TYPE_NONE; + + return GTK_TYPE_WIDGET; +} + +static void +gtk_rotated_bin_add (GtkContainer *container, + GtkWidget *widget) +{ + GtkRotatedBin *bin = GTK_ROTATED_BIN (container); + + if (!bin->child) + { + gtk_widget_set_parent_window (widget, bin->offscreen_window); + gtk_widget_set_parent (widget, GTK_WIDGET (bin)); + bin->child = widget; + } + else + g_warning ("GtkRotatedBin cannot have more than one child\n"); +} + +static void +gtk_rotated_bin_remove (GtkContainer *container, + GtkWidget *widget) +{ + GtkRotatedBin *bin = GTK_ROTATED_BIN (container); + gboolean was_visible; + + was_visible = GTK_WIDGET_VISIBLE (widget); + + if (bin->child == widget) + { + gtk_widget_unparent (widget); + + bin->child = NULL; + + if (was_visible && GTK_WIDGET_VISIBLE (container)) + gtk_widget_queue_resize (GTK_WIDGET (container)); + } +} + +static void +gtk_rotated_bin_forall (GtkContainer *container, + gboolean include_internals, + GtkCallback callback, + gpointer callback_data) +{ + GtkRotatedBin *bin = GTK_ROTATED_BIN (container); + + g_return_if_fail (callback != NULL); + + if (bin->child) + (*callback) (bin->child, callback_data); +} + +void +gtk_rotated_bin_set_angle (GtkRotatedBin *bin, + gdouble angle) +{ + g_return_if_fail (GTK_IS_ROTATED_BIN (bin)); + + bin->angle = angle; + gtk_widget_queue_resize (GTK_WIDGET (bin)); + + gdk_window_geometry_changed (bin->offscreen_window); +} + +static void +gtk_rotated_bin_size_request (GtkWidget *widget, + GtkRequisition *requisition) +{ + GtkRotatedBin *bin = GTK_ROTATED_BIN (widget); + GtkRequisition child_requisition; + double s, c; + double w, h; + + child_requisition.width = 0; + child_requisition.height = 0; + + if (bin->child && GTK_WIDGET_VISIBLE (bin->child)) + gtk_widget_size_request (bin->child, &child_requisition); + + s = sin (bin->angle); + c = cos (bin->angle); + w = c * child_requisition.width + s * child_requisition.height; + h = s * child_requisition.width + c * child_requisition.height; + + requisition->width = GTK_CONTAINER (widget)->border_width * 2 + w; + requisition->height = GTK_CONTAINER (widget)->border_width * 2 + h; +} + +static void +gtk_rotated_bin_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) +{ + GtkRotatedBin *bin = GTK_ROTATED_BIN (widget); + gint border_width; + gint w, h; + gdouble s, c; + + widget->allocation = *allocation; + + border_width = GTK_CONTAINER (widget)->border_width; + + w = allocation->width - border_width * 2; + h = allocation->height - border_width * 2; + + if (GTK_WIDGET_REALIZED (widget)) + gdk_window_move_resize (widget->window, + allocation->x + border_width, + allocation->y + border_width, + w, h); + + if (bin->child && GTK_WIDGET_VISIBLE (bin->child)) + { + GtkRequisition child_requisition; + GtkAllocation child_allocation; + + s = sin (bin->angle); + c = cos (bin->angle); + + gtk_widget_get_child_requisition (bin->child, &child_requisition); + child_allocation.x = 0; + child_allocation.y = 0; + child_allocation.height = child_requisition.height; + if (c == 0.0) + child_allocation.width = h / s; + else if (s == 0.0) + child_allocation.width = w / c; + else + child_allocation.width = MIN ((w - s * child_allocation.height) / c, + (h - c * child_allocation.height) / s); + + if (GTK_WIDGET_REALIZED (widget)) + gdk_window_move_resize (bin->offscreen_window, + child_allocation.x, + child_allocation.y, + child_allocation.width, + child_allocation.height); + + child_allocation.x = child_allocation.y = 0; + gtk_widget_size_allocate (bin->child, &child_allocation); + } +} + +static gboolean +gtk_rotated_bin_damage (GtkWidget *widget, + GdkEventExpose *event) +{ + gdk_window_invalidate_rect (widget->window, NULL, FALSE); + + return TRUE; +} + +static gboolean +gtk_rotated_bin_expose (GtkWidget *widget, + GdkEventExpose *event) +{ + GtkRotatedBin *bin = GTK_ROTATED_BIN (widget); + gint width, height; + gdouble s, c; + gdouble w, h; + + if (GTK_WIDGET_DRAWABLE (widget)) + { + if (event->window == widget->window) + { + GdkPixmap *pixmap; + GtkAllocation child_area; + cairo_t *cr; + + if (bin->child && GTK_WIDGET_VISIBLE (bin->child)) + { + pixmap = gdk_offscreen_window_get_pixmap (bin->offscreen_window); + child_area = bin->child->allocation; + + cr = gdk_cairo_create (widget->window); + + /* transform */ + s = sin (bin->angle); + c = cos (bin->angle); + w = c * child_area.width + s * child_area.height; + h = s * child_area.width + c * child_area.height; + + cairo_translate (cr, (w - child_area.width) / 2, (h - child_area.height) / 2); + cairo_translate (cr, child_area.width / 2, child_area.height / 2); + cairo_rotate (cr, bin->angle); + cairo_translate (cr, -child_area.width / 2, -child_area.height / 2); + + /* clip */ + gdk_drawable_get_size (pixmap, &width, &height); + cairo_rectangle (cr, 0, 0, width, height); + cairo_clip (cr); + /* paint */ + gdk_cairo_set_source_pixmap (cr, pixmap, 0, 0); + cairo_paint (cr); + + cairo_destroy (cr); + } + } + else if (event->window == bin->offscreen_window) + { + gtk_paint_flat_box (widget->style, event->window, + GTK_STATE_NORMAL, GTK_SHADOW_NONE, + &event->area, widget, "blah", + 0, 0, -1, -1); + + if (bin->child) + gtk_container_propagate_expose (GTK_CONTAINER (widget), + bin->child, + event); + } + } + + return FALSE; +} + +/*** ***/ + +static void +scale_changed (GtkRange *range, + GtkRotatedBin *bin) +{ + gtk_rotated_bin_set_angle (bin, gtk_range_get_value (range)); +} + +static GtkWidget *window = NULL; + +GtkWidget * +do_offscreen_window (GtkWidget *do_widget) +{ + if (!window) + { + GtkWidget *bin, *vbox, *scale, *button; + GdkColor black; + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_screen (GTK_WINDOW (window), + gtk_widget_get_screen (do_widget)); + gtk_window_set_title (GTK_WINDOW (window), "Rotated widget"); + + g_signal_connect (window, "destroy", + G_CALLBACK (gtk_widget_destroyed), &window); + + gdk_color_parse ("black", &black); + gtk_widget_modify_bg (window, GTK_STATE_NORMAL, &black); + gtk_container_set_border_width (GTK_CONTAINER (window), 10); + + vbox = gtk_vbox_new (0, FALSE); + scale = gtk_hscale_new_with_range (0, G_PI/2, 0.01); + gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE); + + button = gtk_button_new_with_label ("A Button"); + bin = gtk_rotated_bin_new (); + + g_signal_connect (scale, "value-changed", G_CALLBACK (scale_changed), bin); + + gtk_container_add (GTK_CONTAINER (window), vbox); + gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox), bin, TRUE, TRUE, 0); + gtk_container_add (GTK_CONTAINER (bin), button); + } + + if (!GTK_WIDGET_VISIBLE (window)) + gtk_widget_show_all (window); + else + { + gtk_widget_destroy (window); + window = NULL; + } + + return window; +} + diff --git a/demos/gtk-demo/offscreen_window2.c b/demos/gtk-demo/offscreen_window2.c new file mode 100644 index 0000000000..19ca760bda --- /dev/null +++ b/demos/gtk-demo/offscreen_window2.c @@ -0,0 +1,500 @@ +/* Offscreen windows/Effects + * + * Offscreen windows can be used to render elements multiple times to achieve + * various effects. + */ +#include + +#define GTK_TYPE_MIRROR_BIN (gtk_mirror_bin_get_type ()) +#define GTK_MIRROR_BIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_MIRROR_BIN, GtkMirrorBin)) +#define GTK_MIRROR_BIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_MIRROR_BIN, GtkMirrorBinClass)) +#define GTK_IS_MIRROR_BIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_MIRROR_BIN)) +#define GTK_IS_MIRROR_BIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_MIRROR_BIN)) +#define GTK_MIRROR_BIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_MIRROR_BIN, GtkMirrorBinClass)) + +typedef struct _GtkMirrorBin GtkMirrorBin; +typedef struct _GtkMirrorBinClass GtkMirrorBinClass; + +struct _GtkMirrorBin +{ + GtkContainer container; + + GtkWidget *child; + GdkWindow *offscreen_window; +}; + +struct _GtkMirrorBinClass +{ + GtkContainerClass parent_class; +}; + +GType gtk_mirror_bin_get_type (void) G_GNUC_CONST; +GtkWidget* gtk_mirror_bin_new (void); + +/*** implementation ***/ + +static void gtk_mirror_bin_realize (GtkWidget *widget); +static void gtk_mirror_bin_unrealize (GtkWidget *widget); +static void gtk_mirror_bin_size_request (GtkWidget *widget, + GtkRequisition *requisition); +static void gtk_mirror_bin_size_allocate (GtkWidget *widget, + GtkAllocation *allocation); +static gboolean gtk_mirror_bin_damage (GtkWidget *widget, + GdkEventExpose *event); +static gboolean gtk_mirror_bin_expose (GtkWidget *widget, + GdkEventExpose *offscreen); + +static void gtk_mirror_bin_add (GtkContainer *container, + GtkWidget *child); +static void gtk_mirror_bin_remove (GtkContainer *container, + GtkWidget *widget); +static void gtk_mirror_bin_forall (GtkContainer *container, + gboolean include_internals, + GtkCallback callback, + gpointer callback_data); +static GType gtk_mirror_bin_child_type (GtkContainer *container); + +G_DEFINE_TYPE (GtkMirrorBin, gtk_mirror_bin, GTK_TYPE_CONTAINER); + +static void +to_child (GtkMirrorBin *bin, + double widget_x, + double widget_y, + double *x_out, + double *y_out) +{ + *x_out = widget_x; + *y_out = widget_y; +} + +static void +to_parent (GtkMirrorBin *bin, + double offscreen_x, + double offscreen_y, + double *x_out, + double *y_out) +{ + *x_out = offscreen_x; + *y_out = offscreen_y; +} + +static void +gtk_mirror_bin_class_init (GtkMirrorBinClass *klass) +{ + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass); + + widget_class->realize = gtk_mirror_bin_realize; + widget_class->unrealize = gtk_mirror_bin_unrealize; + widget_class->size_request = gtk_mirror_bin_size_request; + widget_class->size_allocate = gtk_mirror_bin_size_allocate; + widget_class->expose_event = gtk_mirror_bin_expose; + + g_signal_override_class_closure (g_signal_lookup ("damage-event", GTK_TYPE_WIDGET), + GTK_TYPE_MIRROR_BIN, + g_cclosure_new (G_CALLBACK (gtk_mirror_bin_damage), + NULL, NULL)); + + container_class->add = gtk_mirror_bin_add; + container_class->remove = gtk_mirror_bin_remove; + container_class->forall = gtk_mirror_bin_forall; + container_class->child_type = gtk_mirror_bin_child_type; +} + +static void +gtk_mirror_bin_init (GtkMirrorBin *bin) +{ + GTK_WIDGET_UNSET_FLAGS (bin, GTK_NO_WINDOW); +} + +GtkWidget * +gtk_mirror_bin_new (void) +{ + return g_object_new (GTK_TYPE_MIRROR_BIN, NULL); +} + +static GdkWindow * +pick_offscreen_child (GdkWindow *offscreen_window, + double widget_x, + double widget_y, + GtkMirrorBin *bin) +{ + GtkAllocation child_area; + double x, y; + + if (bin->child && GTK_WIDGET_VISIBLE (bin->child)) + { + to_child (bin, widget_x, widget_y, &x, &y); + + child_area = bin->child->allocation; + + if (x >= 0 && x < child_area.width && + y >= 0 && y < child_area.height) + return bin->offscreen_window; + } + + return NULL; +} + +static void +offscreen_window_to_parent (GdkWindow *offscreen_window, + double offscreen_x, + double offscreen_y, + double *parent_x, + double *parent_y, + GtkMirrorBin *bin) +{ + to_parent (bin, offscreen_x, offscreen_y, parent_x, parent_y); +} + +static void +offscreen_window_from_parent (GdkWindow *window, + double parent_x, + double parent_y, + double *offscreen_x, + double *offscreen_y, + GtkMirrorBin *bin) +{ + to_child (bin, parent_x, parent_y, offscreen_x, offscreen_y); +} + +static void +gtk_mirror_bin_realize (GtkWidget *widget) +{ + GtkMirrorBin *bin = GTK_MIRROR_BIN (widget); + GdkWindowAttr attributes; + gint attributes_mask; + gint border_width; + GtkRequisition child_requisition; + + GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); + + border_width = GTK_CONTAINER (widget)->border_width; + + attributes.x = widget->allocation.x + border_width; + attributes.y = widget->allocation.y + border_width; + attributes.width = widget->allocation.width - 2 * border_width; + attributes.height = widget->allocation.height - 2 * border_width; + attributes.window_type = GDK_WINDOW_CHILD; + attributes.event_mask = gtk_widget_get_events (widget) + | GDK_EXPOSURE_MASK + | GDK_POINTER_MOTION_MASK + | GDK_BUTTON_PRESS_MASK + | GDK_BUTTON_RELEASE_MASK + | GDK_SCROLL_MASK + | GDK_ENTER_NOTIFY_MASK + | GDK_LEAVE_NOTIFY_MASK; + + attributes.visual = gtk_widget_get_visual (widget); + attributes.colormap = gtk_widget_get_colormap (widget); + attributes.wclass = GDK_INPUT_OUTPUT; + + attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; + + widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), + &attributes, attributes_mask); + gdk_window_set_user_data (widget->window, widget); + g_signal_connect (widget->window, "pick-embedded-child", + G_CALLBACK (pick_offscreen_child), bin); + + attributes.window_type = GDK_WINDOW_OFFSCREEN; + + child_requisition.width = child_requisition.height = 0; + if (bin->child && GTK_WIDGET_VISIBLE (bin->child)) + { + attributes.width = bin->child->allocation.width; + attributes.height = bin->child->allocation.height; + } + bin->offscreen_window = gdk_window_new (gtk_widget_get_root_window (widget), + &attributes, attributes_mask); + gdk_window_set_user_data (bin->offscreen_window, widget); + if (bin->child) + gtk_widget_set_parent_window (bin->child, bin->offscreen_window); + gdk_offscreen_window_set_embedder (bin->offscreen_window, widget->window); + g_signal_connect (bin->offscreen_window, "to-embedder", + G_CALLBACK (offscreen_window_to_parent), bin); + g_signal_connect (bin->offscreen_window, "from-embedder", + G_CALLBACK (offscreen_window_from_parent), bin); + + widget->style = gtk_style_attach (widget->style, widget->window); + + gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL); + gtk_style_set_background (widget->style, bin->offscreen_window, GTK_STATE_NORMAL); + gdk_window_show (bin->offscreen_window); +} + +static void +gtk_mirror_bin_unrealize (GtkWidget *widget) +{ + GtkMirrorBin *bin = GTK_MIRROR_BIN (widget); + + gdk_window_set_user_data (bin->offscreen_window, NULL); + gdk_window_destroy (bin->offscreen_window); + bin->offscreen_window = NULL; + + GTK_WIDGET_CLASS (gtk_mirror_bin_parent_class)->unrealize (widget); +} + +static GType +gtk_mirror_bin_child_type (GtkContainer *container) +{ + GtkMirrorBin *bin = GTK_MIRROR_BIN (container); + + if (bin->child) + return G_TYPE_NONE; + + return GTK_TYPE_WIDGET; +} + +static void +gtk_mirror_bin_add (GtkContainer *container, + GtkWidget *widget) +{ + GtkMirrorBin *bin = GTK_MIRROR_BIN (container); + + if (!bin->child) + { + gtk_widget_set_parent_window (widget, bin->offscreen_window); + gtk_widget_set_parent (widget, GTK_WIDGET (bin)); + bin->child = widget; + } + else + g_warning ("GtkMirrorBin cannot have more than one child\n"); +} + +static void +gtk_mirror_bin_remove (GtkContainer *container, + GtkWidget *widget) +{ + GtkMirrorBin *bin = GTK_MIRROR_BIN (container); + gboolean was_visible; + + was_visible = GTK_WIDGET_VISIBLE (widget); + + if (bin->child == widget) + { + gtk_widget_unparent (widget); + + bin->child = NULL; + + if (was_visible && GTK_WIDGET_VISIBLE (container)) + gtk_widget_queue_resize (GTK_WIDGET (container)); + } +} + +static void +gtk_mirror_bin_forall (GtkContainer *container, + gboolean include_internals, + GtkCallback callback, + gpointer callback_data) +{ + GtkMirrorBin *bin = GTK_MIRROR_BIN (container); + + g_return_if_fail (callback != NULL); + + if (bin->child) + (*callback) (bin->child, callback_data); +} + +static void +gtk_mirror_bin_size_request (GtkWidget *widget, + GtkRequisition *requisition) +{ + GtkMirrorBin *bin = GTK_MIRROR_BIN (widget); + GtkRequisition child_requisition; + + child_requisition.width = 0; + child_requisition.height = 0; + + if (bin->child && GTK_WIDGET_VISIBLE (bin->child)) + gtk_widget_size_request (bin->child, &child_requisition); + + requisition->width = GTK_CONTAINER (widget)->border_width * 2 + child_requisition.width + 10; + requisition->height = GTK_CONTAINER (widget)->border_width * 2 + child_requisition.height * 2 + 10; +} + +static void +gtk_mirror_bin_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) +{ + GtkMirrorBin *bin = GTK_MIRROR_BIN (widget); + gint border_width; + gint w, h; + widget->allocation = *allocation; + + border_width = GTK_CONTAINER (widget)->border_width; + + w = allocation->width - border_width * 2; + h = allocation->height - border_width * 2; + + if (GTK_WIDGET_REALIZED (widget)) + gdk_window_move_resize (widget->window, + allocation->x + border_width, + allocation->y + border_width, + w, h); + + if (bin->child && GTK_WIDGET_VISIBLE (bin->child)) + { + GtkRequisition child_requisition; + GtkAllocation child_allocation; + + gtk_widget_get_child_requisition (bin->child, &child_requisition); + child_allocation.x = 0; + child_allocation.y = 0; + child_allocation.height = child_requisition.height; + child_allocation.width = child_requisition.width; + + if (GTK_WIDGET_REALIZED (widget)) + gdk_window_move_resize (bin->offscreen_window, + allocation->x + border_width, + allocation->y + border_width, + child_allocation.width, child_allocation.height); + gtk_widget_size_allocate (bin->child, &child_allocation); + } +} + +static gboolean +gtk_mirror_bin_damage (GtkWidget *widget, + GdkEventExpose *event) +{ + gdk_window_invalidate_rect (widget->window, NULL, FALSE); + + return TRUE; +} + +static gboolean +gtk_mirror_bin_expose (GtkWidget *widget, + GdkEventExpose *event) +{ + GtkMirrorBin *bin = GTK_MIRROR_BIN (widget); + gint width, height; + + if (GTK_WIDGET_DRAWABLE (widget)) + { + if (event->window == widget->window) + { + GdkPixmap *pixmap; + cairo_t *cr; + cairo_matrix_t matrix; + cairo_pattern_t *mask; + + if (bin->child && GTK_WIDGET_VISIBLE (bin->child)) + { + pixmap = gdk_offscreen_window_get_pixmap (bin->offscreen_window); + gdk_drawable_get_size (pixmap, &width, &height); + + cr = gdk_cairo_create (widget->window); + + cairo_save (cr); + + cairo_rectangle (cr, 0, 0, width, height); + cairo_clip (cr); + + /* paint the offscreen child */ + gdk_cairo_set_source_pixmap (cr, pixmap, 0, 0); + cairo_paint (cr); + + cairo_restore (cr); + + cairo_matrix_init (&matrix, 1.0, 0.0, 0.3, 1.0, 0.0, 0.0); + cairo_matrix_scale (&matrix, 1.0, -1.0); + cairo_matrix_translate (&matrix, -10, - 3 * height - 10); + cairo_transform (cr, &matrix); + + cairo_rectangle (cr, 0, height, width, height); + cairo_clip (cr); + + gdk_cairo_set_source_pixmap (cr, pixmap, 0, height); + + /* create linear gradient as mask-pattern to fade out the source */ + mask = cairo_pattern_create_linear (0.0, height, 0.0, 2*height); + cairo_pattern_add_color_stop_rgba (mask, 0.0, 0.0, 0.0, 0.0, 0.0); + cairo_pattern_add_color_stop_rgba (mask, 0.25, 0.0, 0.0, 0.0, 0.01); + cairo_pattern_add_color_stop_rgba (mask, 0.5, 0.0, 0.0, 0.0, 0.25); + cairo_pattern_add_color_stop_rgba (mask, 0.75, 0.0, 0.0, 0.0, 0.5); + cairo_pattern_add_color_stop_rgba (mask, 1.0, 0.0, 0.0, 0.0, 1.0); + + /* paint the reflection */ + cairo_mask (cr, mask); + + cairo_pattern_destroy (mask); + cairo_destroy (cr); + } + } + else if (event->window == bin->offscreen_window) + { + gtk_paint_flat_box (widget->style, event->window, + GTK_STATE_NORMAL, GTK_SHADOW_NONE, + &event->area, widget, "blah", + 0, 0, -1, -1); + + if (bin->child) + gtk_container_propagate_expose (GTK_CONTAINER (widget), + bin->child, + event); + } + } + + return FALSE; +} + +/*** ***/ + +static GtkWidget *window = NULL; + +GtkWidget * +do_offscreen_window2 (GtkWidget *do_widget) +{ + if (!window) + { + GtkWidget *bin, *vbox; + GtkWidget *hbox, *entry, *applybutton, *backbutton; + GtkSizeGroup *group; + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_screen (GTK_WINDOW (window), + gtk_widget_get_screen (do_widget)); + gtk_window_set_title (GTK_WINDOW (window), "Effects"); + + g_signal_connect (window, "destroy", + G_CALLBACK (gtk_widget_destroyed), &window); + + gtk_container_set_border_width (GTK_CONTAINER (window), 10); + + vbox = gtk_vbox_new (0, FALSE); + + bin = gtk_mirror_bin_new (); + + group = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL); + + hbox = gtk_hbox_new (FALSE, 6); + backbutton = gtk_button_new (); + gtk_container_add (GTK_CONTAINER (backbutton), + gtk_image_new_from_stock (GTK_STOCK_GO_BACK, 4)); + gtk_size_group_add_widget (group, backbutton); + entry = gtk_entry_new (); + gtk_size_group_add_widget (group, entry); + applybutton = gtk_button_new (); + gtk_size_group_add_widget (group, applybutton); + gtk_container_add (GTK_CONTAINER (applybutton), + gtk_image_new_from_stock (GTK_STOCK_APPLY, 4)); + + gtk_container_add (GTK_CONTAINER (window), vbox); + gtk_box_pack_start (GTK_BOX (vbox), bin, TRUE, TRUE, 0); + gtk_container_add (GTK_CONTAINER (bin), hbox); + gtk_box_pack_start (GTK_BOX (hbox), backbutton, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (hbox), applybutton, FALSE, FALSE, 0); + } + + if (!GTK_WIDGET_VISIBLE (window)) + gtk_widget_show_all (window); + else + { + gtk_widget_destroy (window); + window = NULL; + } + + return window; +} + diff --git a/demos/gtk-demo/printing.c b/demos/gtk-demo/printing.c index a2d1647a82..124eed905f 100644 --- a/demos/gtk-demo/printing.c +++ b/demos/gtk-demo/printing.c @@ -166,6 +166,7 @@ do_printing (GtkWidget *do_widget) gtk_print_operation_set_use_full_page (operation, FALSE); gtk_print_operation_set_unit (operation, GTK_UNIT_POINTS); + gtk_print_operation_set_embed_page_setup (operation, TRUE); settings = gtk_print_settings_new (); dir = g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS); @@ -173,6 +174,8 @@ do_printing (GtkWidget *do_widget) dir = g_get_home_dir (); if (g_strcmp0 (gtk_print_settings_get (settings, GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT), "ps") == 0) ext = ".ps"; + else if (g_strcmp0 (gtk_print_settings_get (settings, GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT), "svg") == 0) + ext = ".svg"; else ext = ".pdf"; diff --git a/docs/reference/gdk/gdk-docs.sgml b/docs/reference/gdk/gdk-docs.sgml index 50d14a4dc5..6d482744d0 100644 --- a/docs/reference/gdk/gdk-docs.sgml +++ b/docs/reference/gdk/gdk-docs.sgml @@ -103,5 +103,9 @@ Index of new symbols in 2.16 + + + Index of new symbols in 2.18 + diff --git a/docs/reference/gdk/gdk-sections.txt b/docs/reference/gdk/gdk-sections.txt index ce37ae1399..43d000c709 100644 --- a/docs/reference/gdk/gdk-sections.txt +++ b/docs/reference/gdk/gdk-sections.txt @@ -640,6 +640,7 @@ gdk_window_at_pointer gdk_window_show gdk_window_show_unraised gdk_window_hide +gdk_window_is_destroyed gdk_window_is_visible gdk_window_is_viewable gdk_window_get_state @@ -661,6 +662,8 @@ gdk_window_resize gdk_window_move_resize gdk_window_scroll gdk_window_move_region +gdk_window_flush +gdk_window_ensure_native gdk_window_reparent gdk_window_clear gdk_window_clear_area @@ -668,6 +671,7 @@ gdk_window_clear_area_e gdk_window_copy_area gdk_window_raise gdk_window_lower +gdk_window_restack gdk_window_focus gdk_window_register_dnd gdk_window_begin_resize_drag @@ -719,6 +723,7 @@ gdk_window_set_background gdk_window_set_back_pixmap GDK_PARENT_RELATIVE gdk_window_set_cursor +gdk_window_get_cursor gdk_window_set_colormap gdk_window_get_user_data gdk_window_get_geometry @@ -739,6 +744,7 @@ gdk_window_get_colormap gdk_window_get_type gdk_window_get_origin gdk_window_get_deskrelative_origin +gdk_window_get_root_coords gdk_window_get_pointer GdkModifierType gdk_window_get_parent @@ -767,6 +773,10 @@ GdkPointerHooks gdk_set_pointer_hooks +gdk_offscreen_window_get_pixmap +gdk_offscreen_window_set_embedder +gdk_offscreen_window_get_embedder +gdk_window_geometry_changed gdk_window_redirect_to_drawable gdk_window_remove_redirection @@ -905,6 +915,7 @@ gdk_cairo_set_source_pixbuf gdk_cairo_set_source_pixmap gdk_cairo_rectangle gdk_cairo_region +gdk_cairo_reset_clip
@@ -931,6 +942,7 @@ gdk_region_get_clipbox gdk_region_get_rectangles gdk_region_empty gdk_region_equal +gdk_region_rect_equal gdk_region_point_in gdk_region_rect_in GdkOverlapType diff --git a/docs/reference/gdk/tmpl/cairo_interaction.sgml b/docs/reference/gdk/tmpl/cairo_interaction.sgml index ea570c8158..7ada736cf6 100644 --- a/docs/reference/gdk/tmpl/cairo_interaction.sgml +++ b/docs/reference/gdk/tmpl/cairo_interaction.sgml @@ -85,3 +85,12 @@ Cairo paths and to use pixbufs as sources for drawing operations. @region: + + + + + +@cr: +@drawable: + + diff --git a/docs/reference/gdk/tmpl/events.sgml b/docs/reference/gdk/tmpl/events.sgml index b4dff1b5ef..9174b9db0d 100644 --- a/docs/reference/gdk/tmpl/events.sgml +++ b/docs/reference/gdk/tmpl/events.sgml @@ -94,6 +94,7 @@ for the possible window states was added in 2.8. @GDK_DAMAGE: the content of the window has been changed. This event type was added in 2.14. +@GDK_EVENT_LAST: marks the end of the GdkEventType enumeration. Added in 2.18 diff --git a/docs/reference/gdk/tmpl/keys.sgml b/docs/reference/gdk/tmpl/keys.sgml index b8ade0ccbe..ac3baf17b1 100644 --- a/docs/reference/gdk/tmpl/keys.sgml +++ b/docs/reference/gdk/tmpl/keys.sgml @@ -15,6 +15,11 @@ header file. <gdk/gdkkeysyms.h> is not included in +Key values are regularly updated from the upstream X.org X11 implementation, +so new values are added regularly. They will be prefixed with GDK_ rather than +XF86XK_ or XK_ (for older symbols). + + Key values can be converted into a string representation using gdk_keyval_name(). The reverse function, converting a string to a key value, is provided by gdk_keyval_from_name(). diff --git a/docs/reference/gdk/tmpl/regions.sgml b/docs/reference/gdk/tmpl/regions.sgml index 6c58600217..c05c2641c3 100644 --- a/docs/reference/gdk/tmpl/regions.sgml +++ b/docs/reference/gdk/tmpl/regions.sgml @@ -175,6 +175,16 @@ included in the region, while areas overlapped an even number of times are not. @Returns: + + + + + +@region: +@rectangle: +@Returns: + + diff --git a/docs/reference/gdk/tmpl/windows.sgml b/docs/reference/gdk/tmpl/windows.sgml index 195aabb6a4..7c58ac39f6 100644 --- a/docs/reference/gdk/tmpl/windows.sgml +++ b/docs/reference/gdk/tmpl/windows.sgml @@ -8,10 +8,18 @@ Onscreen display areas in the target window system A #GdkWindow is a rectangular region on the screen. It's a low-level object, used to implement high-level objects such as #GtkWidget and #GtkWindow on the -GTK+ level. A #GtkWindow is a toplevel window, the thing a user might think of -as a "window" with a titlebar and so on; a #GtkWindow may contain many #GdkWindow. +GTK+ level. A #GtkWindow is a toplevel window, the thing a user might think of +as a "window" with a titlebar and so on; a #GtkWindow may contain many #GdkWindow. For example, each #GtkButton has a #GdkWindow associated with it. +Composited Windows + +Normally, the windowing system takes care of rendering the contents of a child +window onto its parent window. This mechanism can be intercepted by calling +gdk_window_set_composited() on the child window. For a +composited window it is the responsibility of the +application to render the window contents at the right spot. + Composited windows @@ -54,7 +62,7 @@ transparent_expose (GtkWidget *widget, * this handler is called after the red has been drawn. If it was * called before then GTK would just blindly paint over our work. * - * Note: if the child window has children, then you need a cairo 1.16 + * Note: if the child window has children, then you need a cairo 1.6 * feature to make this work correctly. */ static gboolean @@ -153,10 +161,10 @@ main (int argc, char **argv) ]]> -In the example , a button is -placed inside of an event box inside of a window. The event box is -set as composited and therefore is no longer automatically drawn to -the screen. +In the example , a button is +placed inside of an event box inside of a window. The event box is +set as composited and therefore is no longer automatically drawn to +the screen. When the contents of the event box change, an expose event is @@ -168,8 +176,31 @@ that it wishes. In our case, we merge the contents with a 50% transparency. We also set the background colour of the window to red. The effect is -that the background shows through the button. +that the background shows through the button. + +Offscreen Windows + +Offscreen windows are more general than composited windows, since they +allow not only to modify the rendering of the child window onto its parent, +but also to apply coordinate transformations. + + +To integrate an offscreen window into a window hierarchy, one has to call +gdk_window_set_embedder() and handle a number of signals. The +gdk_offscreen_window_set_embedder() and handle a number of signals. The +#GdkWindow::pick-embedded-child signal on the embedder window is used to +select an offscreen child at given coordinates, and the #GdkWindow::to-embedder +and #GdkWindow::from-embedder signals on the offscreen window are used to +translate coordinates between the embedder and the offscreen window. + + + +For rendering an offscreen window onto its embedder, the contents of the +offscreen window are available as a pixmap, via +gdk_offscreen_window_get_pixmap(). + + @@ -189,6 +220,43 @@ these types. + + + + + +@gdkwindow: the object which received the signal. +@arg1: +@arg2: +@arg3: +@arg4: + + + + + + +@gdkwindow: the object which received the signal. +@arg1: +@arg2: +@Returns: + + + + + + +@gdkwindow: the object which received the signal. +@arg1: +@arg2: +@arg3: +@arg4: + + + + + + Describes the kind of window. @@ -200,6 +268,7 @@ Describes the kind of window. @GDK_WINDOW_DIALOG: useless/deprecated compatibility type @GDK_WINDOW_TEMP: override redirect temporary window (used to implement #GtkMenu) @GDK_WINDOW_FOREIGN: foreign window (see gdk_window_foreign_new()) +@GDK_WINDOW_OFFSCREEN: offscreen window (see ). Since 2.18 @@ -497,6 +566,15 @@ Deprecated equivalent of g_object_unref() @window: + + + + + +@window: +@Returns: + + @@ -685,6 +763,23 @@ Deprecated equivalent of g_object_unref() @dy: + + + + + +@window: + + + + + + + +@window: +@Returns: + + @@ -764,6 +859,16 @@ Deprecated equivalent to gdk_draw_drawable(), see that function for docs @window: + + + + + +@window: +@sibling: +@above: + + @@ -1200,6 +1305,15 @@ window. @cursor: + + + + + +@window: +@Returns: + + Deprecated equivalent to gdk_drawable_set_colormap() @@ -1384,6 +1498,18 @@ Deprecated equivalent of gdk_drawable_get_type(). @Returns: + + + + + +@window: +@x: +@y: +@root_x: +@root_y: + + @@ -1659,12 +1785,39 @@ Applications should never have any reason to use this facility @Returns: - + + + + + +@window: +@Returns: + + + + + + + +@window: +@embedder: + + + + + + + +@window: +@Returns: + + + + + + + +@window: @@ -1690,3 +1843,11 @@ End: @window: + + + diff --git a/docs/reference/gtk/Makefile.am b/docs/reference/gtk/Makefile.am index 72aed73800..6a0b30acdb 100644 --- a/docs/reference/gtk/Makefile.am +++ b/docs/reference/gtk/Makefile.am @@ -129,6 +129,7 @@ content_files = \ drawing-model.xml \ glossary.xml \ migrating-checklist.sgml \ + migrating-ClientSideWindows.sgml \ migrating-GtkAboutDialog.sgml \ migrating-GtkAction.sgml \ migrating-GtkAssistant.sgml \ @@ -159,6 +160,7 @@ expand_content_files = \ drawing-model.xml \ glossary.xml \ migrating-checklist.sgml \ + migrating-ClientSideWindows.sgml \ migrating-GtkAction.sgml \ migrating-GtkComboBox.sgml \ migrating-GtkEntry-icons.sgml \ @@ -168,6 +170,7 @@ expand_content_files = \ migrating-GtkColorButton.sgml \ migrating-GtkAssistant.sgml \ migrating-GtkRecentChooser.sgml \ + migrating-GtkLabel-links.sgml \ migrating-GtkLinkButton.sgml \ migrating-GtkBuilder.sgml \ migrating-GtkTooltip.sgml \ diff --git a/docs/reference/gtk/gtk-docs.sgml b/docs/reference/gtk/gtk-docs.sgml index 16a59b0f1e..e6e2fe401e 100644 --- a/docs/reference/gtk/gtk-docs.sgml +++ b/docs/reference/gtk/gtk-docs.sgml @@ -177,6 +177,7 @@ that is, GUI components such as #GtkButton or #GtkTextView. Numeric/Text Data Entry + @@ -434,6 +435,7 @@ that is, GUI components such as #GtkButton or #GtkTextView. + diff --git a/docs/reference/gtk/gtk-sections.txt b/docs/reference/gtk/gtk-sections.txt index 45712f3d03..3e4d4906f7 100644 --- a/docs/reference/gtk/gtk-sections.txt +++ b/docs/reference/gtk/gtk-sections.txt @@ -1268,7 +1268,10 @@ gtk_old_editable_get_type GtkEntry GtkEntry gtk_entry_new +gtk_entry_new_with_buffer gtk_entry_new_with_max_length +gtk_entry_get_buffer +gtk_entry_set_buffer gtk_entry_set_text gtk_entry_append_text gtk_entry_prepend_text @@ -1342,6 +1345,34 @@ GTK_ENTRY_GET_CLASS gtk_entry_get_type
+
+gtkentrybuffer +GtkEntryBuffer +GtkEntryBuffer +gtk_entry_buffer_new +gtk_entry_buffer_get_text +gtk_entry_buffer_set_text +gtk_entry_buffer_get_bytes +gtk_entry_buffer_get_length +gtk_entry_buffer_get_max_length +gtk_entry_buffer_set_max_length +gtk_entry_buffer_insert_text +gtk_entry_buffer_delete_text +gtk_entry_buffer_emit_deleted_text +gtk_entry_buffer_emit_inserted_text + + +GTK_ENTRY_BUFFER +GTK_IS_ENTRY_BUFFER +GTK_TYPE_ENTRY_BUFFER +GTK_ENTRY_BUFFER_CLASS +GTK_IS_ENTRY_BUFFER_CLASS +GTK_ENTRY_BUFFER_GET_CLASS +GTK_ENTRY_BUFFER_MAX_SIZE + +gtk_entry_buffer_get_type +
+
gtkentrycompletion GtkEntryCompletion @@ -1452,6 +1483,8 @@ gtk_file_chooser_set_show_hidden gtk_file_chooser_get_show_hidden gtk_file_chooser_set_do_overwrite_confirmation gtk_file_chooser_get_do_overwrite_confirmation +gtk_file_chooser_set_create_folders +gtk_file_chooser_get_create_folders gtk_file_chooser_set_current_name gtk_file_chooser_get_filename gtk_file_chooser_set_filename @@ -1939,6 +1972,8 @@ gtk_icon_view_set_column_spacing gtk_icon_view_get_column_spacing gtk_icon_view_set_margin gtk_icon_view_get_margin +gtk_icon_view_set_item_padding +gtk_icon_view_get_item_padding gtk_icon_view_select_path gtk_icon_view_unselect_path gtk_icon_view_path_is_selected @@ -2275,6 +2310,8 @@ gtk_label_set_use_underline gtk_label_set_single_line_mode gtk_label_set_angle gtk_label_get_current_uri +gtk_label_set_track_visited_links +gtk_label_get_track_visited_links GTK_LABEL GTK_IS_LABEL @@ -2421,7 +2458,7 @@ gtk_menu_set_monitor gtk_menu_get_monitor gtk_menu_get_tearoff_state gtk_menu_set_reserve_toggle_size -get_menu_get_reserve_toggle_size +gtk_menu_get_reserve_toggle_size gtk_menu_popdown gtk_menu_reposition @@ -3037,6 +3074,8 @@ gtk_range_set_lower_stepper_sensitivity gtk_range_get_lower_stepper_sensitivity gtk_range_set_upper_stepper_sensitivity gtk_range_get_upper_stepper_sensitivity +gtk_range_get_flippable +gtk_range_set_flippable GTK_RANGE GTK_IS_RANGE @@ -4995,6 +5034,14 @@ gtk_cell_renderer_editing_canceled gtk_cell_renderer_stop_editing gtk_cell_renderer_get_fixed_size gtk_cell_renderer_set_fixed_size +gtk_cell_renderer_get_visible +gtk_cell_renderer_set_visible +gtk_cell_renderer_get_sensitive +gtk_cell_renderer_set_sensitive +gtk_cell_renderer_get_alignment +gtk_cell_renderer_set_alignment +gtk_cell_renderer_get_padding +gtk_cell_renderer_set_padding GTK_CELL_RENDERER @@ -5100,6 +5147,9 @@ gtk_cell_renderer_toggle_get_radio gtk_cell_renderer_toggle_set_radio gtk_cell_renderer_toggle_get_active gtk_cell_renderer_toggle_set_active +gtk_cell_renderer_toggle_get_activatable +gtk_cell_renderer_toggle_set_activatable + GTK_CELL_RENDERER_TOGGLE GTK_IS_CELL_RENDERER_TOGGLE @@ -5529,6 +5579,30 @@ gtk_widget_set_has_tooltip gtk_widget_trigger_tooltip_query gtk_widget_get_snapshot gtk_widget_get_window +gtk_widget_get_allocation +gtk_widget_set_allocation +gtk_widget_get_app_paintable +gtk_widget_get_can_default +gtk_widget_set_can_default +gtk_widget_get_can_focus +gtk_widget_set_can_focus +gtk_widget_get_double_buffered +gtk_widget_get_has_window +gtk_widget_set_has_window +gtk_widget_get_sensitive +gtk_widget_is_sensitive +gtk_widget_get_state +gtk_widget_get_visible +gtk_widget_set_visible +gtk_widget_has_default +gtk_widget_has_focus +gtk_widget_has_grab +gtk_widget_is_drawable +gtk_widget_is_toplevel +gtk_widget_set_window +gtk_widget_set_receives_default +gtk_widget_get_receives_default + gtk_requisition_copy gtk_requisition_free @@ -6554,6 +6628,7 @@ gtk_print_operation_set_print_settings gtk_print_operation_get_print_settings gtk_print_operation_set_job_name gtk_print_operation_set_n_pages +gtk_print_operation_get_n_pages_to_print gtk_print_operation_set_current_page gtk_print_operation_set_use_full_page gtk_print_operation_set_unit @@ -6572,6 +6647,8 @@ gtk_print_operation_set_support_selection gtk_print_operation_get_support_selection gtk_print_operation_set_has_selection gtk_print_operation_get_has_selection +gtk_print_operation_set_embed_page_setup +gtk_print_operation_get_embed_page_setup gtk_print_run_page_setup_dialog GtkPageSetupDoneFunc gtk_print_run_page_setup_dialog_async @@ -6620,6 +6697,9 @@ gtk_print_unix_dialog_set_support_selection gtk_print_unix_dialog_get_support_selection gtk_print_unix_dialog_set_has_selection gtk_print_unix_dialog_get_has_selection +gtk_print_unix_dialog_set_embed_page_setup +gtk_print_unix_dialog_get_embed_page_setup +gtk_print_unix_dialog_get_page_setup_set GtkPrintCapabilities gtk_print_unix_dialog_set_manual_capabilities gtk_print_unix_dialog_get_manual_capabilities diff --git a/docs/reference/gtk/gtk.types b/docs/reference/gtk/gtk.types index 126f673bb1..d743aa1e1a 100644 --- a/docs/reference/gtk/gtk.types +++ b/docs/reference/gtk/gtk.types @@ -48,6 +48,7 @@ gtk_curve_get_type gtk_dialog_get_type gtk_drawing_area_get_type gtk_editable_get_type +gtk_entry_buffer_get_type gtk_entry_completion_get_type gtk_entry_get_type gtk_event_box_get_type diff --git a/docs/reference/gtk/migrating-ClientSideWindows.sgml b/docs/reference/gtk/migrating-ClientSideWindows.sgml new file mode 100644 index 0000000000..845e9561b2 --- /dev/null +++ b/docs/reference/gtk/migrating-ClientSideWindows.sgml @@ -0,0 +1,70 @@ + + + + + Migrating to client-side windows + + + In version 2.18, GDK has been changed to use client-side windows. This + means that there is no longer a 1-1 correspondence between #GdkWindows + and windows in the underlying window system. In particular, it is no + longer correct to assume that each window has an associated XID. + Code that makes this assumption can sometimes be fixed by calling + gdk_window_ensure_native() on the windows in question. + Calling gdk_x11_drawable_get_xid() (or GDK_WINDOW_XID()) from the + X11-specific API on a non-native window will explicitly call + gdk_window_ensure_native(), so old code using this will continue to + work. A small gotcha is that the GDK_WINDOW_XID() call is no longer a + trivial accessor for the XID of the window, and thus must not be called + from another thread without taking locking precautions. + + + + GDK looks for the GDK_NATIVE_WINDOWS environment variable + and makes all windows native if it is set. It also tries to be more + compatible with the way prior versions worked in some other ways. + + + + Some applications assume that they can just operate on the X windows + corresponding to their GDK windows without ever telling GDK. One + example that we've seen is changing the child window stacking order + using XRestackWindows(). Fixing this properly requires to fix the code + to use GDK functions to achieve whatever it is trying to achieve. + To make this easier in the case of stacking order changes, we've added + a gdk_window_restack() function. + + + + One change that can cause problems for some applications is that GDK + is more aggressive about optimizing away expose events. Code that does + more than just repainting exposed areas in response to expose events + may be affected by this. + + + + Problems can also occur when using cairo for drawing. One thing that can + go wrong is clip handling. If you ever need to reset the clip region on + a cairo_t (i.e. use cairo_reset_clip()), you have to to use + gdk_cairo_reset_clip() instead. The reason for this is that the cairo_reset_clip() call will remove the initial clip region that limits your drawing to + the client-side window at hand, so you will end up drawing over stuff + outside the window. You also need to use gdk_cairo_reset_clip() if you + use a cairo_t that was not allocated in a double-buffered expose handler + and keep it in use after window hierarchy changes (resizing, moving, + stacking order changes). The easiest fix for this kind of problem is to + simply create a new cairo context for each expose event. + + + + Due to a weird API in XClearArea the gdk_window_clear_area() call handled + a specified width or height of zero to mean "to end of window" for + non-double-buffered drawing. This has been changed to be consistent with + the docs and what happens in the double-buffered case. All code in GTK+ + that relied on this has been fixed, but it is possible (although unlikely) + that third party applications rely on this. If you need to do this, just + implement it yourself using gdk_drawable_get_size(). + + + diff --git a/docs/reference/gtk/migrating-GtkBuilder.sgml b/docs/reference/gtk/migrating-GtkBuilder.sgml index d18eaf89fe..1fd843c8a6 100644 --- a/docs/reference/gtk/migrating-GtkBuilder.sgml +++ b/docs/reference/gtk/migrating-GtkBuilder.sgml @@ -13,21 +13,18 @@ - A good way to start a migration from libglade to GtkBuilder is - to run the gtk-builder-convert - utility on your glade file, and inspect the resulting output. - If your code uses the @root parameter of glade_xml_new(), you - may want to split your glade file into multiple GtkBuilder files - by using the option of - gtk-builder-convert. Alternatively, you - can use gtk_builder_add_objects_from_file() to construct only certain + A good way to start a migration from libglade to GtkBuilder is using + glade3 to convert your .glade file. + If your code uses the @root parameter of glade_xml_new(), + you can use gtk_builder_add_objects_from_file() to construct only certain objects from a GtkBuilder file. - Alternatively, you can open the glade file with - glade3 and then save it in GtkBuilder - format. This is supported by glade3 since version 3.6. + Alternatively, GTK+ also offers the + gtk-builder-convert script you can use + to do the conversion; in which case you should be careful to inspect the output + and make sure you didn't lose any data. @@ -53,7 +50,7 @@ GError* error = NULL; GtkBuilder* builder = gtk_builder_new (); if (!gtk_builder_add_from_file (builder, FILE, &error)) { - g_warning ("Couldn't load builder file: %amp;s", error->message); + g_warning ("Couldn't load builder file: %s", error->message); g_error_free (error); } diff --git a/docs/reference/gtk/migrating-GtkEntry-icons.sgml b/docs/reference/gtk/migrating-GtkEntry-icons.sgml index ce3b44dcbc..93e21b5356 100644 --- a/docs/reference/gtk/migrating-GtkEntry-icons.sgml +++ b/docs/reference/gtk/migrating-GtkEntry-icons.sgml @@ -7,10 +7,10 @@ Migrating from SexyIconEntry to GtkEntry - GTK+ 2.16 supports showing icons inside a #GtkEntry, similar to - SexyIconEntry. Porting from SexyIconEntry to GtkEntry is relatively - straightforward. The main difference between the two APIs is that - SexyIconEntry uses #GtkImage widgets in a somewhat awkward way as + GTK+ 2.16 supports showing icons inside a #GtkEntry, similar to + SexyIconEntry. Porting from SexyIconEntry to GtkEntry is relatively + straightforward. The main difference between the two APIs is that + SexyIconEntry uses #GtkImage widgets in a somewhat awkward way as storage vehicles for icons, while GtkEntry allows to specify icons via pixbufs, stock ids, icon names or #GIcons. So, if your code uses e.g.: @@ -130,7 +130,7 @@ text_changed_cb (GtkEntry *entry, gtk_entry_set_icon_from_stock (GTK_ENTRY (entry), GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLEAR); - g_signal_connect (entry, "icon-pressed", + g_signal_connect (entry, "icon-press", G_CALLBACK (icon_pressed_cb), NULL); g_signal_connect (entry, "notify::text", G_CALLBACK (text_changed_cb), find_button); diff --git a/docs/reference/gtk/migrating-GtkIconView.sgml b/docs/reference/gtk/migrating-GtkIconView.sgml index 6707729575..f1fe85264e 100644 --- a/docs/reference/gtk/migrating-GtkIconView.sgml +++ b/docs/reference/gtk/migrating-GtkIconView.sgml @@ -130,7 +130,7 @@ GtkIconView: - GnomeIconListMode is replaced by the + GnomeIconListMode is replaced by the orientation property of GtkIconView diff --git a/docs/reference/gtk/running.sgml b/docs/reference/gtk/running.sgml index 4e32c253ed..4c3c97fcdc 100644 --- a/docs/reference/gtk/running.sgml +++ b/docs/reference/gtk/running.sgml @@ -341,6 +341,16 @@ nevertheless. + + <envar>GDK_NATIVE_WINDOWS</envar> + + + If set, GDK creates all windows as native windows. This can help + applications that make assumptions about 1-1 correspondence between + GDK windows and X11 windows. + + + <envar>XDG_DATA_HOME</envar>, <envar>XDG_DATA_DIRS</envar> diff --git a/docs/reference/gtk/tmpl/gtk-unused.sgml b/docs/reference/gtk/tmpl/gtk-unused.sgml index cb2a663eff..4a7c4e2b3b 100644 --- a/docs/reference/gtk/tmpl/gtk-unused.sgml +++ b/docs/reference/gtk/tmpl/gtk-unused.sgml @@ -1033,6 +1033,25 @@ You may not attach these to signals created with the + + + + + +@parent_class: +@inserted_text: +@deleted_text: +@get_text: +@get_length: +@insert_text: +@delete_text: +@_gtk_reserved0: +@_gtk_reserved1: +@_gtk_reserved2: +@_gtk_reserved3: +@_gtk_reserved4: +@_gtk_reserved5: + @@ -3866,14 +3885,6 @@ fundamental type. @group_cycling: @Returns: - - - - - -@widget: -@Returns: - diff --git a/docs/reference/gtk/tmpl/gtkcellrenderer.sgml b/docs/reference/gtk/tmpl/gtkcellrenderer.sgml index cf2a68d63d..98adcd9687 100644 --- a/docs/reference/gtk/tmpl/gtkcellrenderer.sgml +++ b/docs/reference/gtk/tmpl/gtkcellrenderer.sgml @@ -282,3 +282,79 @@ it cannot be individually modified. @height: + + + + + +@cell: +@Returns: + + + + + + + +@cell: +@visible: + + + + + + + +@cell: +@Returns: + + + + + + + +@cell: +@sensitive: + + + + + + + +@cell: +@xalign: +@yalign: + + + + + + + +@cell: +@xalign: +@yalign: + + + + + + + +@cell: +@xpad: +@ypad: + + + + + + + +@cell: +@xpad: +@ypad: + + diff --git a/docs/reference/gtk/tmpl/gtkcellrenderertoggle.sgml b/docs/reference/gtk/tmpl/gtkcellrenderertoggle.sgml index efa09e209a..faacb516e2 100644 --- a/docs/reference/gtk/tmpl/gtkcellrenderertoggle.sgml +++ b/docs/reference/gtk/tmpl/gtkcellrenderertoggle.sgml @@ -103,3 +103,21 @@ property. When activated, it emits the toggled signal. @setting: + + + + + +@toggle: +@Returns: + + + + + + + +@toggle: +@setting: + + diff --git a/docs/reference/gtk/tmpl/gtkentry.sgml b/docs/reference/gtk/tmpl/gtkentry.sgml index 385e7235e7..59a95c68fb 100644 --- a/docs/reference/gtk/tmpl/gtkentry.sgml +++ b/docs/reference/gtk/tmpl/gtkentry.sgml @@ -173,6 +173,11 @@ The #GtkEntry-struct struct contains only private data. + + + + + @@ -401,6 +406,15 @@ The #GtkEntry-struct struct contains only private data. @Returns: + + + + + +@buffer: +@Returns: + + @@ -409,6 +423,24 @@ The #GtkEntry-struct struct contains only private data. @Returns: + + + + + +@entry: +@Returns: + + + + + + + +@entry: +@buffer: + + diff --git a/docs/reference/gtk/tmpl/gtkentrybuffer.sgml b/docs/reference/gtk/tmpl/gtkentrybuffer.sgml new file mode 100644 index 0000000000..712f013153 --- /dev/null +++ b/docs/reference/gtk/tmpl/gtkentrybuffer.sgml @@ -0,0 +1,168 @@ + +GtkEntryBuffer + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@entrybuffer: the object which received the signal. +@arg1: +@arg2: + + + + + + +@entrybuffer: the object which received the signal. +@arg1: +@arg2: +@arg3: + + + + + + + + + + + + + + + + + + + + + +@initial_chars: +@n_initial_chars: +@Returns: + + + + + + + +@buffer: +@Returns: + + + + + + + +@buffer: +@chars: +@n_chars: + + + + + + + +@buffer: +@Returns: + + + + + + + +@buffer: +@Returns: + + + + + + + +@buffer: +@Returns: + + + + + + + +@buffer: +@max_length: + + + + + + + +@buffer: +@position: +@chars: +@n_chars: +@Returns: + + + + + + + +@buffer: +@position: +@n_chars: +@Returns: + + + + + + + +@buffer: +@position: +@n_chars: + + + + + + + +@buffer: +@position: +@chars: +@n_chars: + + diff --git a/docs/reference/gtk/tmpl/gtkfilechooser.sgml b/docs/reference/gtk/tmpl/gtkfilechooser.sgml index 7258bcb9bf..c88131e4e6 100644 --- a/docs/reference/gtk/tmpl/gtkfilechooser.sgml +++ b/docs/reference/gtk/tmpl/gtkfilechooser.sgml @@ -677,6 +677,11 @@ gtk_widget_destroy (chooser); + + + + + @@ -875,6 +880,24 @@ gtk_widget_destroy (chooser); @Returns: + + + + + +@chooser: +@create_folders: + + + + + + + +@chooser: +@Returns: + + diff --git a/docs/reference/gtk/tmpl/gtkiconview.sgml b/docs/reference/gtk/tmpl/gtkiconview.sgml index 5ee9accc5d..1fc99d1233 100644 --- a/docs/reference/gtk/tmpl/gtkiconview.sgml +++ b/docs/reference/gtk/tmpl/gtkiconview.sgml @@ -109,6 +109,11 @@ private fields and should not be directly accessed. + + + + + @@ -491,6 +496,24 @@ selected rows. It will be called on every selected row in the view. @Returns: + + + + + +@icon_view: +@item_padding: + + + + + + + +@icon_view: +@Returns: + + diff --git a/docs/reference/gtk/tmpl/gtkimage.sgml b/docs/reference/gtk/tmpl/gtkimage.sgml index b7e3fd8b7f..be25e081a1 100644 --- a/docs/reference/gtk/tmpl/gtkimage.sgml +++ b/docs/reference/gtk/tmpl/gtkimage.sgml @@ -196,7 +196,7 @@ functions), but they will all return %NULL values. @GTK_IMAGE_ANIMATION: the widget contains a #GdkPixbufAnimation @GTK_IMAGE_ICON_NAME: the widget contains a named icon. This image type was added in GTK+ 2.6 -@GTK_IMAGE_GICON: the widgte contains a #GIcon. +@GTK_IMAGE_GICON: the widget contains a #GIcon. This image type was added in GTK+ 2.14 diff --git a/docs/reference/gtk/tmpl/gtklabel.sgml b/docs/reference/gtk/tmpl/gtklabel.sgml index 19be444368..96168bf36b 100644 --- a/docs/reference/gtk/tmpl/gtklabel.sgml +++ b/docs/reference/gtk/tmpl/gtklabel.sgml @@ -301,6 +301,11 @@ described below. + + + + + @@ -746,3 +751,21 @@ Sets the text within the GtkLabel widget. @Returns: + + + + + +@label: +@track_links: + + + + + + + +@label: +@Returns: + + diff --git a/docs/reference/gtk/tmpl/gtkmenu.sgml b/docs/reference/gtk/tmpl/gtkmenu.sgml index 20d2c201cd..c8d837692b 100644 --- a/docs/reference/gtk/tmpl/gtkmenu.sgml +++ b/docs/reference/gtk/tmpl/gtkmenu.sgml @@ -119,6 +119,11 @@ should be accessed using the functions below. + + + + + @@ -354,6 +359,24 @@ See gtk_menu_set_accel_group(). @Returns: + + + + + +@menu: +@reserve_toggle_size: + + + + + + + +@menu: +@Returns: + + Removes the menu from the screen. diff --git a/docs/reference/gtk/tmpl/gtkmenutoolbutton.sgml b/docs/reference/gtk/tmpl/gtkmenutoolbutton.sgml index 2da6c3b2bd..f55163fe01 100644 --- a/docs/reference/gtk/tmpl/gtkmenutoolbutton.sgml +++ b/docs/reference/gtk/tmpl/gtkmenutoolbutton.sgml @@ -19,19 +19,21 @@ A GtkToolItem containing a button with an additional dropdown menu - - #GtkToolbar - The toolbar widget - #GtkToolButton - - - The parent class of #GtkMenuToolButton. The properties - "label_widget", "label", "icon_widget", and "stock_id" on - #GtkToolButton determine the label and icon used on - #GtkMenuToolButtons. - - - + + + #GtkToolbar + The toolbar widget + #GtkToolButton + + + The parent class of #GtkMenuToolButton. The properties + "label_widget", "label", "icon_widget", and "stock_id" on + #GtkToolButton determine the label and icon used on + #GtkMenuToolButtons. + + + + diff --git a/docs/reference/gtk/tmpl/gtkprintoperation.sgml b/docs/reference/gtk/tmpl/gtkprintoperation.sgml index 7d9ae6f463..9228734d48 100644 --- a/docs/reference/gtk/tmpl/gtkprintoperation.sgml +++ b/docs/reference/gtk/tmpl/gtkprintoperation.sgml @@ -208,6 +208,11 @@ Printing support was added in GTK+ 2.10. + + + + + @@ -228,6 +233,11 @@ Printing support was added in GTK+ 2.10. + + + + + @@ -414,6 +424,15 @@ The #GQuark used for #GtkPrintError errors. @n_pages: + + + + + +@op: +@Returns: + + @@ -576,6 +595,24 @@ The #GQuark used for #GtkPrintError errors. @Returns: + + + + + +@op: +@embed: + + + + + + + +@op: +@Returns: + + diff --git a/docs/reference/gtk/tmpl/gtkprintunixdialog.sgml b/docs/reference/gtk/tmpl/gtkprintunixdialog.sgml index 882a4746de..4a732b3bec 100644 --- a/docs/reference/gtk/tmpl/gtkprintunixdialog.sgml +++ b/docs/reference/gtk/tmpl/gtkprintunixdialog.sgml @@ -90,6 +90,11 @@ The GtkPrintUnixDialog implementation of the GtkBuildable interface exposes its + + + + + @@ -239,6 +244,33 @@ The GtkPrintUnixDialog implementation of the GtkBuildable interface exposes its @Returns: + + + + + +@dialog: +@embed: + + + + + + + +@dialog: +@Returns: + + + + + + + +@dialog: +@Returns: + + An enum for specifying which features the print dialog should offer. @@ -256,7 +288,7 @@ formats are supported. the printer in PDF format @GTK_PRINT_CAPABILITY_GENERATE_PS: The program will send the document to the printer in Postscript format -@GTK_PRINT_CAPABILITY_PREVIEW: Print dialog will offer a previe +@GTK_PRINT_CAPABILITY_PREVIEW: Print dialog will offer a preview @GTK_PRINT_CAPABILITY_NUMBER_UP: Print dialog will offer printing multiple pages per sheet. Since 2.12 @GTK_PRINT_CAPABILITY_NUMBER_UP_LAYOUT: Print dialog will allow to rearrange diff --git a/docs/reference/gtk/tmpl/gtkrange.sgml b/docs/reference/gtk/tmpl/gtkrange.sgml index a9c92f75da..3f24667239 100644 --- a/docs/reference/gtk/tmpl/gtkrange.sgml +++ b/docs/reference/gtk/tmpl/gtkrange.sgml @@ -346,3 +346,21 @@ at the end of range widgets. @Returns: + + + + + +@range: +@Returns: + + + + + + + +@range: +@flippable: + + diff --git a/docs/reference/gtk/tmpl/gtksettings.sgml b/docs/reference/gtk/tmpl/gtksettings.sgml index 5219c1a6c2..cdc4a173df 100644 --- a/docs/reference/gtk/tmpl/gtksettings.sgml +++ b/docs/reference/gtk/tmpl/gtksettings.sgml @@ -23,7 +23,7 @@ realized at least once. The following example demonstrates a way to do this: gtk_init (&argc, &argv); - /* make sure the type is realized &ast/ + /* make sure the type is realized */ g_type_class_unref (g_type_class_ref (GTK_TYPE_IMAGE_MENU_ITEM)); g_object_set (gtk_settings_get_default (), "gtk-menu-images", FALSE, NULL); diff --git a/docs/reference/gtk/tmpl/gtkstatusicon.sgml b/docs/reference/gtk/tmpl/gtkstatusicon.sgml index 640a0e1302..77e69c14d6 100644 --- a/docs/reference/gtk/tmpl/gtkstatusicon.sgml +++ b/docs/reference/gtk/tmpl/gtkstatusicon.sgml @@ -172,6 +172,11 @@ on Win32 doesn't allow to embed arbitrary widgets. + + + + + @@ -420,6 +425,24 @@ on Win32 doesn't allow to embed arbitrary widgets. @Returns: + + + + + +@status_icon: +@title: + + + + + + + +@status_icon: +@Returns: + + diff --git a/docs/reference/gtk/tmpl/gtktoggletoolbutton.sgml b/docs/reference/gtk/tmpl/gtktoggletoolbutton.sgml index 9582e0bfbb..21a12e9dec 100644 --- a/docs/reference/gtk/tmpl/gtktoggletoolbutton.sgml +++ b/docs/reference/gtk/tmpl/gtktoggletoolbutton.sgml @@ -19,25 +19,27 @@ A GtkToolItem containing a toggle button - - #GtkToolbar - The toolbar widget - #GtkToolButton - - - The parent class of #GtkToggleToolButton. The properties - "label_widget", "label", "icon_widget", and "stock_id" on - #GtkToolButton determine the label and icon used on - #GtkToggleToolButtons. - - - #GtkSeparatorToolItem - - A subclass of #GtkToolItem that separates groups of - items on a toolbar. - - - + + + #GtkToolbar + The toolbar widget + #GtkToolButton + + + The parent class of #GtkToggleToolButton. The properties + "label_widget", "label", "icon_widget", and "stock_id" on + #GtkToolButton determine the label and icon used on + #GtkToggleToolButtons. + + + #GtkSeparatorToolItem + + A subclass of #GtkToolItem that separates groups of + items on a toolbar. + + + + diff --git a/docs/reference/gtk/tmpl/gtktoolitem.sgml b/docs/reference/gtk/tmpl/gtktoolitem.sgml index a7a30455b0..348de3fc99 100644 --- a/docs/reference/gtk/tmpl/gtktoolitem.sgml +++ b/docs/reference/gtk/tmpl/gtktoolitem.sgml @@ -12,23 +12,6 @@ GtkToolItem - - #GtkToolbar - The toolbar widget - - - - #GtkToolButton - A subclass of #GtkToolItem that displays buttons on - the toolbar - - - - #GtkSeparatorToolItem - A subclass of #GtkToolItem that separates groups of - items on a toolbar - - diff --git a/docs/reference/gtk/tmpl/gtktreeviewcolumn.sgml b/docs/reference/gtk/tmpl/gtktreeviewcolumn.sgml index 7412707106..96cb94b98e 100644 --- a/docs/reference/gtk/tmpl/gtktreeviewcolumn.sgml +++ b/docs/reference/gtk/tmpl/gtktreeviewcolumn.sgml @@ -112,6 +112,11 @@ calling gtk_tree_view_column_set_cell_data_func() + + + + + diff --git a/docs/reference/gtk/tmpl/gtkwidget.sgml b/docs/reference/gtk/tmpl/gtkwidget.sgml index 664288e9cb..c127bfc225 100644 --- a/docs/reference/gtk/tmpl/gtkwidget.sgml +++ b/docs/reference/gtk/tmpl/gtkwidget.sgml @@ -693,6 +693,11 @@ internal child "accessible" of a GtkWidget. + + + + + @@ -2636,6 +2641,213 @@ This function is deprecated; it does nothing. @Returns: + + + + + +@widget: +@allocation: + + + + + + + +@widget: +@allocation: + + + + + + + +@widget: +@Returns: + + + + + + + +@widget: +@Returns: + + + + + + + +@widget: +@can_default: + + + + + + + +@widget: +@Returns: + + + + + + + +@widget: +@can_focus: + + + + + + + +@widget: +@Returns: + + + + + + + +@widget: +@Returns: + + + + + + + +@widget: +@has_window: + + + + + + + +@widget: +@Returns: + + + + + + + +@widget: +@Returns: + + + + + + + +@widget: +@Returns: + + + + + + + +@widget: +@Returns: + + + + + + + +@widget: +@visible: + + + + + + + +@widget: +@Returns: + + + + + + + +@widget: +@Returns: + + + + + + + +@widget: +@Returns: + + + + + + + +@widget: +@Returns: + + + + + + + +@widget: +@Returns: + + + + + + + +@widget: +@window: + + + + + + + +@widget: +@receives_default: + + + + + + + +@widget: +@Returns: + + diff --git a/gdk-pixbuf/gdk-pixbuf-io.c b/gdk-pixbuf/gdk-pixbuf-io.c index bc357bd059..646b0f1eaa 100644 --- a/gdk-pixbuf/gdk-pixbuf-io.c +++ b/gdk-pixbuf/gdk-pixbuf-io.c @@ -277,6 +277,13 @@ correct_prefix (gchar **path) if (strncmp (*path, GTK_PREFIX "/", strlen (GTK_PREFIX "/")) == 0 || strncmp (*path, GTK_PREFIX "\\", strlen (GTK_PREFIX "\\")) == 0) { + gchar *tem = NULL; + if (strlen(*path) > 5 && strncmp (*path - 5, ".libs", 5) == 0) + { + /* We are being run from inside the build tree, and shouldn't mess about. */ + return; + } + /* This is an entry put there by gdk-pixbuf-query-loaders on the * packager's system. On Windows a prebuilt GTK+ package can be * installed in a random location. The gdk-pixbuf.loaders file @@ -284,7 +291,7 @@ correct_prefix (gchar **path) * builder's machine. Replace the build-time prefix with the * installation prefix on this machine. */ - gchar *tem = *path; + tem = *path; *path = g_strconcat (get_toplevel (), tem + strlen (GTK_PREFIX), NULL); g_free (tem); } diff --git a/gdk-pixbuf/io-gdip-utils.c b/gdk-pixbuf/io-gdip-utils.c index 935372516b..3dba9e5a79 100644 --- a/gdk-pixbuf/io-gdip-utils.c +++ b/gdk-pixbuf/io-gdip-utils.c @@ -353,7 +353,6 @@ gdip_buffer_to_bitmap (const gchar *buffer, size_t size, GError **error) if (!hg) return NULL; - IStream_SetSize (stream, *(ULARGE_INTEGER *)&size64); hr = CreateStreamOnHGlobal (hg, FALSE, (LPSTREAM *)&stream); if (!SUCCEEDED (hr)) { @@ -361,7 +360,9 @@ gdip_buffer_to_bitmap (const gchar *buffer, size_t size, GError **error) GlobalFree (hg); return NULL; } - + + IStream_SetSize (stream, *(ULARGE_INTEGER *)&size64); + status = GdipCreateBitmapFromStream (stream, &bitmap); if (Ok != status) diff --git a/gdk-pixbuf/io-gif.c b/gdk-pixbuf/io-gif.c index 0a5803fb0c..04fb1d1170 100644 --- a/gdk-pixbuf/io-gif.c +++ b/gdk-pixbuf/io-gif.c @@ -220,7 +220,7 @@ gif_read (GifContext *context, guchar *buffer, size_t len) G_FILE_ERROR, g_file_error_from_errno (save_errno), _("Failure reading GIF: %s"), - strerror (save_errno)); + g_strerror (save_errno)); } #ifdef IO_GIFDEBUG diff --git a/gdk-pixbuf/io-jpeg.c b/gdk-pixbuf/io-jpeg.c index cf8c9ed195..680a209041 100644 --- a/gdk-pixbuf/io-jpeg.c +++ b/gdk-pixbuf/io-jpeg.c @@ -468,7 +468,6 @@ gdk_pixbuf__jpeg_image_load (FILE *f, GError **error) cinfo.err = jpeg_std_error (&jerr.pub); jerr.pub.error_exit = fatal_error_handler; jerr.pub.output_message = output_message_handler; - jerr.error = error; if (sigsetjmp (jerr.setjmp_buffer, 1)) { @@ -1190,11 +1189,11 @@ real_save_jpeg (GdkPixbuf *pixbuf, } /* set up error handling */ + cinfo.err = jpeg_std_error (&(jerr.pub)); jerr.pub.error_exit = fatal_error_handler; jerr.pub.output_message = output_message_handler; jerr.error = error; - cinfo.err = jpeg_std_error (&(jerr.pub)); if (sigsetjmp (jerr.setjmp_buffer, 1)) { jpeg_destroy_compress (&cinfo); g_free (buf); diff --git a/gdk-pixbuf/io-xpm.c b/gdk-pixbuf/io-xpm.c index 4d57cf2da5..b8a02d84cc 100644 --- a/gdk-pixbuf/io-xpm.c +++ b/gdk-pixbuf/io-xpm.c @@ -596,7 +596,7 @@ pixbuf_create_from_xpm (const gchar * (*get_buf) (enum buf_op op, gpointer handl if ((!buffer) || (strlen (buffer) < wbytes)) continue; - for (n = 0, cnt = 0, xcnt = 0; n < wbytes; n += cpp, xcnt++) { + for (n = 0, xcnt = 0; n < wbytes; n += cpp, xcnt++) { strncpy (pixel_str, &buffer[n], cpp); pixel_str[cpp] = 0; diff --git a/gdk-pixbuf/makefile.msc b/gdk-pixbuf/makefile.msc index 62020f4ea0..7f6486afa1 100644 --- a/gdk-pixbuf/makefile.msc +++ b/gdk-pixbuf/makefile.msc @@ -15,11 +15,12 @@ GDK_PIXBUF_VER = 2.0 # but not yet -DINCLUDE_png ##USEGDIP=1 # to get _working_ include modules we need respective defines ... +# BUILT_IN_FORMATS = \ !IFDEF USEGDIP -DINCLUDE_gdiplus \ !ELSE - -DINCLUDE_bmp -DINCLUDE_gif -DINCLUDE_ico -DINCLUDE_jpeg -DINCLUDE_tiff \ + -DINCLUDE_bmp -DINCLUDE_gif -DINCLUDE_ico -DINCLUDE_jpeg -DINCLUDE_tiff \ !ENDIF -DINCLUDE_png \ -DINCLUDE_xpm -DINCLUDE_wbmp \ diff --git a/gdk-pixbuf/queryloaders.c b/gdk-pixbuf/queryloaders.c index ba81638992..71805d43ee 100644 --- a/gdk-pixbuf/queryloaders.c +++ b/gdk-pixbuf/queryloaders.c @@ -119,17 +119,20 @@ loader_sanity_check (const char *path, GdkPixbufFormat *info, GdkPixbufModule *v return 0; } -static void +static void write_loader_info (const char *path, GdkPixbufFormat *info) { const GdkPixbufModulePattern *pattern; - char **mime; - char **ext; + char **mime; + char **ext; g_printf("\"%s\"\n", path); - g_printf ("\"%s\" %u \"%s\" \"%s\" \"%s\"\n", - info->name, info->flags, - info->domain ? info->domain : GETTEXT_PACKAGE, info->description, info->license); + g_printf ("\"%s\" %u \"%s\" \"%s\" \"%s\"\n", + info->name, + info->flags, + info->domain ? info->domain : GETTEXT_PACKAGE, + info->description, + info->license ? info->license : ""); for (mime = info->mime_types; *mime; mime++) { g_printf ("\"%s\" ", *mime); } diff --git a/gdk/Makefile.am b/gdk/Makefile.am index 52a5bf0460..9dc9d6e564 100644 --- a/gdk/Makefile.am +++ b/gdk/Makefile.am @@ -120,6 +120,7 @@ gdk_c_sources = \ gdkintl.h \ gdkkeys.c \ gdkkeyuni.c \ + gdkoffscreenwindow.c \ gdkpango.c \ gdkpixbuf-drawable.c \ gdkpixbuf-render.c \ @@ -151,10 +152,10 @@ gdk_built_sources = \ gdkincludedir = $(includedir)/gtk-2.0/gdk gdkinclude_HEADERS = $(gdk_public_h_sources) $(gdk_built_public_sources) -# gdkmarshalers.c is not here because it is currently an empty file common_sources = \ $(gdk_c_sources) \ gdkenumtypes.c \ + gdkmarshalers.c \ gdkmarshalers.h libgdk_directfb_2_0_la_SOURCES = $(common_sources) @@ -268,11 +269,11 @@ gdkenumtypes.c: @REBUILD@ $(gdk_public_h_sources) gdkenumtypes.c.template # Marshaller generation # gdkmarshalers.h: @REBUILD@ gdkmarshalers.list - $(GLIB_GENMARSHAL) --prefix=gdk_marshal $(srcdir)/gdkmarshalers.list --header > gdkmarshalers-h.tmp \ + $(GLIB_GENMARSHAL) --prefix=_gdk_marshal $(srcdir)/gdkmarshalers.list --header > gdkmarshalers-h.tmp \ && mv gdkmarshalers-h.tmp gdkmarshalers.h \ || ( rm -f gdkmarshalers-h.tmp && exit 1) gdkmarshalers.c: @REBUILD@ gdkmarshalers.list - (echo "#include \"gdkalias.h\""; $(GLIB_GENMARSHAL) --prefix=gdk_marshal $(srcdir)/gdkmarshalers.list --body) > gdkmarshalers-c.tmp \ + (echo "#include \"gdkalias.h\""; $(GLIB_GENMARSHAL) --prefix=_gdk_marshal $(srcdir)/gdkmarshalers.list --body) > gdkmarshalers-c.tmp \ && mv gdkmarshalers-c.tmp gdkmarshalers.c \ || ( rm -f gdkmarshalers-c.tmp && exit 1 ) diff --git a/gdk/directfb/gdkdirectfb.h b/gdk/directfb/gdkdirectfb.h index 6febb72e9a..bc2ba7a00a 100644 --- a/gdk/directfb/gdkdirectfb.h +++ b/gdk/directfb/gdkdirectfb.h @@ -68,12 +68,14 @@ extern gboolean gdk_directfb_monochrome_fonts; void gdk_directfb_window_set_opacity (GdkWindow *window, guchar opacity); +#ifndef GDK_DISABLE_DEPRECATED GdkWindow * gdk_directfb_window_new (GdkWindow *parent, GdkWindowAttr *attributes, gint attributes_mask, DFBWindowCapabilities window_caps, DFBWindowOptions window_options, DFBSurfaceCapabilities surface_caps); +#endif /* GDK_DISABLE_DEPRECATED */ GdkVisual * gdk_directfb_visual_by_format (DFBSurfacePixelFormat pixel_format); diff --git a/gdk/directfb/gdkdisplay-directfb.c b/gdk/directfb/gdkdisplay-directfb.c index 143ff1ad8f..1b8d2456f2 100644 --- a/gdk/directfb/gdkdisplay-directfb.c +++ b/gdk/directfb/gdkdisplay-directfb.c @@ -57,9 +57,8 @@ const GOptionEntry _gdk_windowing_args[] = { NULL} }; -/** - Main entry point for gdk in 2.6 args are parsed -**/ +/* Main entry point for gdk in 2.6 args are parsed + */ GdkDisplay * gdk_display_open (const gchar *display_name) { IDirectFB *directfb; @@ -378,16 +377,18 @@ gdk_directfb_pointer_ungrab (guint32 time, g_object_unref (old_grab_window); } -gint -gdk_display_pointer_is_grabbed (GdkDisplay *display) -{ - return _gdk_directfb_pointer_grab_window != NULL; -} - void -gdk_display_pointer_ungrab (GdkDisplay *display,guint32 time) +gdk_display_pointer_ungrab (GdkDisplay *display, + guint32 time) { - gdk_directfb_pointer_ungrab (time, _gdk_directfb_pointer_implicit_grab); + GdkPointerGrabInfo *grab = _gdk_display_get_last_pointer_grab (display); + + if (grab) + { + grab->serial_end = 0; + } + + _gdk_display_pointer_grab_update (display, 0); } diff --git a/gdk/directfb/gdkdrawable-directfb.c b/gdk/directfb/gdkdrawable-directfb.c index e198881b83..e10f6b11ac 100644 --- a/gdk/directfb/gdkdrawable-directfb.c +++ b/gdk/directfb/gdkdrawable-directfb.c @@ -1600,6 +1600,32 @@ gdk_directfb_cairo_surface_destroy (void *data) impl->cairo_surface = NULL; } +void +_gdk_windowing_set_cairo_surface_size (cairo_surface_t *surface, + int width, + int height) +{ +} + +cairo_surface_t * +_gdk_windowing_create_cairo_surface (GdkDrawable *drawable, + int width, + int height) +{ + GdkDrawableImplDirectFB *impl; + IDirectFB *dfb; + cairo_surface_t *ret; + + impl = GDK_DRAWABLE_IMPL_DIRECTFB (drawable); + dfb = GDK_DISPLAY_DFB (gdk_drawable_get_display (drawable))->directfb; + + ret = cairo_directfb_surface_create (dfb, impl->surface); + cairo_surface_set_user_data (ret, + &gdk_directfb_cairo_key, drawable, + gdk_directfb_cairo_surface_destroy); + + return ret; +} static cairo_surface_t * gdk_directfb_ref_cairo_surface (GdkDrawable *drawable) diff --git a/gdk/directfb/gdkgc-directfb.c b/gdk/directfb/gdkgc-directfb.c index e9cf2ec096..ef83e85ace 100644 --- a/gdk/directfb/gdkgc-directfb.c +++ b/gdk/directfb/gdkgc-directfb.c @@ -351,7 +351,8 @@ gc_unset_clip_mask (GdkGC *gc) void _gdk_windowing_gc_set_clip_region (GdkGC *gc, - const GdkRegion *region) + const GdkRegion *region, + gboolean reset_origin) { GdkGCDirectFB *data; @@ -367,10 +368,13 @@ _gdk_windowing_gc_set_clip_region (GdkGC *gc, else temp_region_reset (&data->clip_region); - gc->clip_x_origin = 0; - gc->clip_y_origin = 0; - data->values.clip_x_origin = 0; - data->values.clip_y_origin = 0; + if (reset_origin) + { + gc->clip_x_origin = 0; + gc->clip_y_origin = 0; + data->values.clip_x_origin = 0; + data->values.clip_y_origin = 0; + } gc_unset_clip_mask (gc); } diff --git a/gdk/directfb/gdkinput-directfb.h b/gdk/directfb/gdkinput-directfb.h index 71f2a008b8..6fd2ae1a00 100644 --- a/gdk/directfb/gdkinput-directfb.h +++ b/gdk/directfb/gdkinput-directfb.h @@ -37,7 +37,6 @@ extern GdkModifierType _gdk_directfb_modifiers; extern int _gdk_directfb_mouse_x, _gdk_directfb_mouse_y; typedef struct _GdkAxisInfo GdkAxisInfo; -typedef struct _GdkInputWindow GdkInputWindow; /* information about a device axis */ struct _GdkAxisInfo diff --git a/gdk/directfb/gdkmain-directfb.c b/gdk/directfb/gdkmain-directfb.c index 8172d47390..3c200b6d2f 100644 --- a/gdk/directfb/gdkmain-directfb.c +++ b/gdk/directfb/gdkmain-directfb.c @@ -59,9 +59,8 @@ void _gdk_windowing_init (void) { - /** - Not that usable called before parse_args - **/ + /* Not that usable called before parse_args + */ } void @@ -370,76 +369,15 @@ gdk_error_trap_pop (void) return 0; } - -/** - * gdk_pointer_grab_info_libgtk_only: - * @grab_window: location to store current grab window - * @owner_events: location to store boolean indicating whether - * the @owner_events flag to gdk_pointer_grab() was %TRUE. - * - * Determines information about the current pointer grab. - * This is not public API and must not be used by applications. - * - * Return value: %TRUE if this application currently has the - * pointer grabbed. - **/ -gboolean -gdk_pointer_grab_info_libgtk_only (GdkDisplay *display,GdkWindow **grab_window, - gboolean *owner_events) -{ - if (_gdk_directfb_pointer_grab_window) - { - if (grab_window) - *grab_window = (GdkWindow *)_gdk_directfb_pointer_grab_window; - if (owner_events) - *owner_events = _gdk_directfb_pointer_grab_owner_events; - - return TRUE; - } - - return FALSE; -} - -/** - * gdk_keyboard_grab_info_libgtk_only: - * @grab_window: location to store current grab window - * @owner_events: location to store boolean indicating whether - * the @owner_events flag to gdk_keyboard_grab() was %TRUE. - * - * Determines information about the current keyboard grab. - * This is not public API and must not be used by applications. - * - * Return value: %TRUE if this application currently has the - * keyboard grabbed. - **/ -gboolean -gdk_keyboard_grab_info_libgtk_only (GdkDisplay *display,GdkWindow **grab_window, - gboolean *owner_events) -{ - if (_gdk_directfb_keyboard_grab_window) - { - if (grab_window) - *grab_window = (GdkWindow *) _gdk_directfb_keyboard_grab_window; - if (owner_events) - *owner_events = _gdk_directfb_keyboard_grab_owner_events; - - return TRUE; - } - - return FALSE; -} - - GdkGrabStatus gdk_keyboard_grab (GdkWindow *window, gint owner_events, guint32 time) { - return gdk_directfb_keyboard_grab(gdk_display_get_default(), - window, - owner_events, - time); - + return gdk_directfb_keyboard_grab (gdk_display_get_default(), + window, + owner_events, + time); } /* @@ -467,35 +405,25 @@ gdk_keyboard_grab (GdkWindow *window, GdkGrabStatus -gdk_display_pointer_grab (GdkDisplay *display,GdkWindow *window, - gint owner_events, - GdkEventMask event_mask, - GdkWindow *confine_to, - GdkCursor *cursor, - guint32 time) +_gdk_windowing_pointer_grab (GdkWindow *window, + GdkWindow *native, + gboolean owner_events, + GdkEventMask event_mask, + GdkWindow *confine_to, + GdkCursor *cursor, + guint32 time) { g_return_val_if_fail (GDK_IS_WINDOW (window), 0); g_return_val_if_fail (confine_to == NULL || GDK_IS_WINDOW (confine_to), 0); - return gdk_directfb_pointer_grab (window, - owner_events, - event_mask, - confine_to, - cursor, - time, - FALSE); -} - -GdkGrabStatus -gdk_pointer_grab (GdkWindow * window, - gint owner_events, - GdkEventMask event_mask, - GdkWindow * confine_to, - GdkCursor * cursor, - guint32 time) -{ - return gdk_directfb_pointer_grab(window, owner_events,event_mask, - confine_to,cursor,time,FALSE); + _gdk_display_add_pointer_grab (_gdk_display, + window, + native, + owner_events, + event_mask, + confine_to, + cursor, + time); } #define __GDK_MAIN_X11_C__ diff --git a/gdk/directfb/gdkpixmap-directfb.c b/gdk/directfb/gdkpixmap-directfb.c index 198b93ccda..b83755ae4c 100644 --- a/gdk/directfb/gdkpixmap-directfb.c +++ b/gdk/directfb/gdkpixmap-directfb.c @@ -114,10 +114,10 @@ gdk_pixmap_impl_directfb_finalize (GObject *object) } GdkPixmap* -gdk_pixmap_new (GdkDrawable *drawable, - gint width, - gint height, - gint depth) +_gdk_pixmap_new (GdkDrawable *drawable, + gint width, + gint height, + gint depth) { DFBSurfacePixelFormat format; IDirectFBSurface *surface; @@ -196,10 +196,10 @@ gdk_pixmap_new (GdkDrawable *drawable, } GdkPixmap * -gdk_bitmap_create_from_data (GdkDrawable *drawable, - const gchar *data, - gint width, - gint height) +_gdk_bitmap_create_from_data (GdkDrawable *drawable, + const gchar *data, + gint width, + gint height) { GdkPixmap *pixmap; @@ -249,13 +249,13 @@ gdk_bitmap_create_from_data (GdkDrawable *drawable, } GdkPixmap* -gdk_pixmap_create_from_data (GdkDrawable *drawable, - const gchar *data, - gint width, - gint height, - gint depth, - const GdkColor *fg, - const GdkColor *bg) +_gdk_pixmap_create_from_data (GdkDrawable *drawable, + const gchar *data, + gint width, + gint height, + gint depth, + const GdkColor *fg, + const GdkColor *bg) { GdkPixmap *pixmap; diff --git a/gdk/directfb/gdkwindow-directfb.c b/gdk/directfb/gdkwindow-directfb.c index af0df3f135..c0ff8e158f 100644 --- a/gdk/directfb/gdkwindow-directfb.c +++ b/gdk/directfb/gdkwindow-directfb.c @@ -51,10 +51,6 @@ #include - - - - D_DEBUG_DOMAIN( GDKDFB_Crossing, "GDKDFB/Crossing", "GDK DirectFB Crossing Events" ); D_DEBUG_DOMAIN( GDKDFB_Updates, "GDKDFB/Updates", "GDK DirectFB Updates" ); D_DEBUG_DOMAIN( GDKDFB_Paintable, "GDKDFB/Paintable", "GDK DirectFB Paintable" ); @@ -69,7 +65,9 @@ static void gdk_window_impl_directfb_class_init (GdkWindowImplDirectFBClass *kla static void gdk_window_impl_directfb_finalize (GObject *object); static void gdk_window_impl_iface_init (GdkWindowImplIface *iface); - +static void gdk_directfb_window_destroy (GdkWindow *window, + gboolean recursing, + gboolean foreign_destroy); typedef struct { @@ -79,115 +77,6 @@ typedef struct } GdkWindowChildHandlerData; -/* Code for dirty-region queueing - */ -static GSList *update_windows = NULL; -static guint update_idle = 0; - -static void -gdk_window_directfb_process_all_updates (void) -{ - GSList *tmp_list; - GSList *old_update_windows = update_windows; - - if (update_idle) - g_source_remove (update_idle); - - update_windows = NULL; - update_idle = 0; - - D_DEBUG_AT( GDKDFB_Updates, "%s()\n", __FUNCTION__ ); - - g_slist_foreach (old_update_windows, (GFunc)g_object_ref, NULL); - tmp_list = old_update_windows; - while (tmp_list) - { - GdkWindowObject *private = GDK_WINDOW_OBJECT( tmp_list->data ); -#ifdef DIRECT_ENABLE_DEBUG - GdkWindowImplDirectFB *wimpl = GDK_WINDOW_IMPL_DIRECTFB (private->impl); -#endif - - if (private->update_freeze_count) - { - D_DEBUG_AT( GDKDFB_Updates, " -> %p frozen [%4d,%4d-%4dx%4d] (%d boxes)\n", - private, DFB_RECTANGLE_VALS_FROM_REGION( &wimpl->flips.bounding ), - wimpl->flips.num_regions ); - update_windows = g_slist_prepend (update_windows, private); - } - else - { - D_DEBUG_AT( GDKDFB_Updates, " -> %p update [%4d,%4d-%4dx%4d] (%d boxes)\n", - private, DFB_RECTANGLE_VALS_FROM_REGION( &wimpl->flips.bounding ), - wimpl->flips.num_regions ); - gdk_window_process_updates(tmp_list->data,TRUE); - } - - g_object_unref (tmp_list->data); - tmp_list = tmp_list->next; - } - -#ifndef GDK_DIRECTFB_NO_EXPERIMENTS - g_slist_foreach (old_update_windows, (GFunc)g_object_ref, NULL); - tmp_list = old_update_windows; - while (tmp_list) - { - GdkWindowObject *top = GDK_WINDOW_OBJECT( gdk_window_get_toplevel( tmp_list->data ) ); - - if (top) - { - GdkWindowImplDirectFB *wimpl = GDK_WINDOW_IMPL_DIRECTFB (top->impl); - - if (wimpl->flips.num_regions) - { - D_DEBUG_AT( GDKDFB_Updates, " -> %p flip [%4d,%4d-%4dx%4d] (%d boxes)\n", - top, DFB_RECTANGLE_VALS_FROM_REGION( &wimpl->flips.bounding ), - wimpl->flips.num_regions ); - - wimpl->drawable.surface->Flip( wimpl->drawable.surface, &wimpl->flips.bounding, DSFLIP_NONE ); - - dfb_updates_reset( &wimpl->flips ); - } - else - D_DEBUG_AT( GDKDFB_Updates, " -> %p has no flips!\n", top ); - } - else - D_DEBUG_AT( GDKDFB_Updates, " -> %p has no top level window!\n", tmp_list->data ); - - g_object_unref (tmp_list->data); - tmp_list = tmp_list->next; - } -#endif - - g_slist_free (old_update_windows); -} - -static gboolean -gdk_window_update_idle (gpointer data) -{ - gdk_window_directfb_process_all_updates (); - - return FALSE; -} - -static void -gdk_window_schedule_update (GdkWindow *window) -{ - D_DEBUG_AT( GDKDFB_Updates, "%s( %p ) <- freeze count %d\n", __FUNCTION__, window, - window ? GDK_WINDOW_OBJECT (window)->update_freeze_count : -1 ); - - if (window && GDK_WINDOW_OBJECT (window)->update_freeze_count) - return; - - if (!update_idle) - { - D_DEBUG_AT( GDKDFB_Updates, " -> adding idle callback\n" ); - - update_idle = gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW, - gdk_window_update_idle, NULL, NULL); - } -} - - static GdkWindow *gdk_directfb_window_containing_pointer = NULL; static GdkWindow *gdk_directfb_focused_window = NULL; static gpointer parent_class = NULL; @@ -424,6 +313,7 @@ _gdk_windowing_window_init (void) private->window_type = GDK_WINDOW_ROOT; private->state = 0; private->children = NULL; + private->viewable = TRUE; // impl->drawable.paint_region = NULL; impl->gdkWindow = _gdk_parent_root; impl->window = NULL; @@ -461,7 +351,6 @@ _gdk_windowing_window_init (void) } - GdkWindow * gdk_directfb_window_new (GdkWindow *parent, GdkWindowAttr *attributes, @@ -558,6 +447,7 @@ gdk_directfb_window_new (GdkWindow *parent, desc.posy = y; desc.width = impl->drawable.width; desc.height = impl->drawable.height; + #if 0 if (window_caps) { @@ -579,16 +469,22 @@ gdk_directfb_window_new (GdkWindow *parent, if (!create_directfb_window (impl, &desc, window_options)) { - g_assert(0); + g_assert(0); _gdk_window_destroy (window, FALSE); + return NULL; } - if( desc.caps != DWCAPS_INPUTONLY ) - impl->window->SetOpacity(impl->window, 0x00 ); + + if (desc.caps != DWCAPS_INPUTONLY) + { + impl->window->SetOpacity(impl->window, 0x00 ); + } + break; case GDK_WINDOW_CHILD: - impl->window=NULL; + impl->window=NULL; + if (!private->input_only && parent_impl->drawable.surface) { @@ -598,12 +494,14 @@ gdk_directfb_window_new (GdkWindow *parent, &rect, &impl->drawable.surface); } + break; default: g_warning ("gdk_window_new: unsupported window type: %d", private->window_type); _gdk_window_destroy (window, FALSE); + return NULL; } @@ -612,28 +510,28 @@ gdk_directfb_window_new (GdkWindow *parent, GdkColormap *colormap; impl->drawable.surface->GetPixelFormat (impl->drawable.surface, - &impl->drawable.format); + &impl->drawable.format); - private->depth = DFB_BITS_PER_PIXEL(impl->drawable.format); + private->depth = DFB_BITS_PER_PIXEL(impl->drawable.format); if ((attributes_mask & GDK_WA_COLORMAP) && attributes->colormap) - { - colormap = attributes->colormap; - } + { + colormap = attributes->colormap; + } else - { - if (gdk_visual_get_system () == visual) - colormap = gdk_colormap_get_system (); - else - colormap =gdk_drawable_get_colormap (parent); - } + { + if (gdk_visual_get_system () == visual) + colormap = gdk_colormap_get_system (); + else + colormap =gdk_drawable_get_colormap (parent); + } gdk_drawable_set_colormap (GDK_DRAWABLE (window), colormap); } else { impl->drawable.format = ((GdkVisualDirectFB *)visual)->format; - private->depth = visual->depth; + private->depth = visual->depth; } gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ? @@ -659,18 +557,176 @@ gdk_directfb_window_new (GdkWindow *parent, return window; } -GdkWindow * -_gdk_window_new (GdkWindow *parent, - GdkWindowAttr *attributes, - gint attributes_mask) + +void +_gdk_window_impl_new (GdkWindow *window, + GdkWindow *real_parent, + GdkScreen *screen, + GdkVisual *visual, + GdkEventMask event_mask, + GdkWindowAttr *attributes, + gint attributes_mask) { - g_return_val_if_fail (attributes != NULL, NULL); + GdkWindowObject *private; + GdkWindowObject *parent_private; + GdkWindowImplDirectFB *impl; + GdkWindowImplDirectFB *parent_impl; + DFBWindowDescription desc; - D_DEBUG_AT( GDKDFB_Window, "%s( %p )\n", __FUNCTION__, parent ); + impl = g_object_new (_gdk_window_impl_get_type (), NULL); + impl->drawable.wrapper = GDK_DRAWABLE (window); + impl->gdkWindow = window; - return gdk_directfb_window_new (parent, attributes, attributes_mask, - DWCAPS_NONE, DWOP_NONE, DSCAPS_NONE); + private = GDK_WINDOW_OBJECT (window); + private->impl = (GdkDrawable *)impl; + + private->x = (attributes_mask & GDK_WA_X) ? attributes->x : 0; + private->y = (attributes_mask & GDK_WA_Y) ? attributes->y : 0; + + parent_private = private->parent; + parent_impl = GDK_WINDOW_IMPL_DIRECTFB (parent_private->impl); + + private->parent = parent_private; + + _gdk_directfb_calc_abs (window); + + impl->drawable.width = MAX (1, attributes->width); + impl->drawable.height = MAX (1, attributes->height); + + private->window_type = attributes->window_type; + + desc.flags = 0; + + switch (attributes->wclass) + { + case GDK_INPUT_OUTPUT: + private->input_only = FALSE; + + desc.flags |= DWDESC_PIXELFORMAT; + desc.pixelformat = ((GdkVisualDirectFB *)visual)->format; + + if (DFB_PIXELFORMAT_HAS_ALPHA (desc.pixelformat)) + { + desc.flags |= DWDESC_CAPS; + desc.caps = DWCAPS_ALPHACHANNEL; + } + + break; + + case GDK_INPUT_ONLY: + private->input_only = TRUE; + desc.flags |= DWDESC_CAPS; + desc.caps = DWCAPS_INPUTONLY; + break; + + default: + g_warning ("_gdk_window_impl_new: unsupported window class\n"); + _gdk_window_destroy (window, FALSE); + return; + } + + switch (private->window_type) + { + case GDK_WINDOW_TOPLEVEL: + case GDK_WINDOW_DIALOG: + case GDK_WINDOW_TEMP: + desc.flags |= (DWDESC_WIDTH | DWDESC_HEIGHT | + DWDESC_POSX | DWDESC_POSY); + desc.posx = private->x; + desc.posy = private->y; + desc.width = impl->drawable.width; + desc.height = impl->drawable.height; + + if (!create_directfb_window (impl, &desc, DWOP_NONE)) + { + g_assert (0); + _gdk_window_destroy (window, FALSE); + + return; + } + + if (desc.caps != DWCAPS_INPUTONLY) + { + impl->window->SetOpacity (impl->window, 0x00); + } + + break; + + case GDK_WINDOW_CHILD: + impl->window = NULL; + + if (!private->input_only && parent_impl->drawable.surface) + { + DFBRectangle rect = { private->x, + private->y, + impl->drawable.width, + impl->drawable.height }; + parent_impl->drawable.surface->GetSubSurface (parent_impl->drawable.surface, + &rect, + &impl->drawable.surface); + } + + break; + + default: + g_warning ("_gdk_window_impl_new: unsupported window type: %d", + private->window_type); + _gdk_window_destroy (window, FALSE); + + return; + } + + if (impl->drawable.surface) + { + GdkColormap *colormap; + + impl->drawable.surface->GetPixelFormat (impl->drawable.surface, + &impl->drawable.format); + + private->depth = DFB_BITS_PER_PIXEL (impl->drawable.format); + + if ((attributes_mask & GDK_WA_COLORMAP) && attributes->colormap) + { + colormap = attributes->colormap; + } + else + { + if (gdk_visual_get_system () == visual) + colormap = gdk_colormap_get_system (); + else + colormap = gdk_colormap_new (visual, FALSE); + } + + gdk_drawable_set_colormap (GDK_DRAWABLE (window), colormap); + } + else + { + impl->drawable.format = ((GdkVisualDirectFB *)visual)->format; + private->depth = visual->depth; + } + + gdk_window_set_cursor (window, + ((attributes_mask & GDK_WA_CURSOR) ? + (attributes->cursor) : NULL)); + + if (parent_private) + parent_private->children = g_list_prepend (parent_private->children, + window); + + /* we hold a reference count on ourself */ + g_object_ref (window); + + if (impl->window) + { + impl->window->GetID (impl->window, &impl->dfb_id); + gdk_directfb_window_id_table_insert (impl->dfb_id, window); + gdk_directfb_event_windows_add (window); + } + + if (attributes_mask & GDK_WA_TYPE_HINT) + gdk_window_set_type_hint (window, attributes->type_hint); } + void _gdk_windowing_window_destroy_foreign (GdkWindow *window) { @@ -678,14 +734,13 @@ _gdk_windowing_window_destroy_foreign (GdkWindow *window) * so reparent it to the root window, and then send * it a delete event, as if we were a WM */ - _gdk_windowing_window_destroy (window,TRUE,TRUE); + gdk_directfb_window_destroy (window, TRUE, TRUE); } - -void -_gdk_windowing_window_destroy (GdkWindow *window, - gboolean recursing, - gboolean foreign_destroy) +static void +gdk_directfb_window_destroy (GdkWindow *window, + gboolean recursing, + gboolean foreign_destroy) { GdkWindowObject *private; GdkWindowImplDirectFB *impl; @@ -709,7 +764,6 @@ _gdk_windowing_window_destroy (GdkWindow *window, if (window == gdk_directfb_focused_window) gdk_directfb_change_focus (NULL); - if (impl->drawable.surface) { GdkDrawableImplDirectFB *dimpl = GDK_DRAWABLE_IMPL_DIRECTFB (private->impl); if(dimpl->cairo_surface) { @@ -1611,96 +1665,6 @@ gdk_directfb_window_reparent (GdkWindow *window, return TRUE; } -static void -gdk_directfb_window_clear_area (GdkWindow *window, - gint x, - gint y, - gint width, - gint height, - gboolean send_expose) -{ - GdkWindowObject *private; - GdkDrawableImplDirectFB *impl; - GdkPixmap *bg_pixmap; - GdkWindowObject *relative_to; - GdkGC *gc = NULL; - gint dx = 0; - gint dy = 0; - - D_DEBUG_AT( GDKDFB_Window, "%s( %p, %4d,%4d-%4dx%4d )\n", __FUNCTION__, window, x, y, width, height ); - - g_return_if_fail (GDK_IS_WINDOW (window)); - - if (GDK_WINDOW_DESTROYED (window)) { - D_DEBUG_AT( GDKDFB_Window, " -> DESTROYED!\n" ); - return; - } - - private = GDK_WINDOW_OBJECT (window); - - impl = GDK_DRAWABLE_IMPL_DIRECTFB (private->impl); - - /** - Follow XClearArea definition for zero height width - **/ - if( width == 0 ) - width = impl->width-x; - if( height == 0 ) - height = impl->height-y; - - bg_pixmap = private->bg_pixmap; - - for (relative_to = private; - relative_to && bg_pixmap == GDK_PARENT_RELATIVE_BG; - relative_to = relative_to->parent) - { - bg_pixmap = relative_to->bg_pixmap; - dx += relative_to->x; - dy += relative_to->y; - } - - if (bg_pixmap == GDK_NO_BG) { - D_DEBUG_AT( GDKDFB_Window, " -> NO BG\n" ); - return; - } - - if (bg_pixmap && bg_pixmap != GDK_PARENT_RELATIVE_BG) - { - GdkGCValues values; - - values.fill = GDK_TILED; - values.tile = bg_pixmap; - values.ts_x_origin = - dx; - values.ts_y_origin = - dy; - - D_DEBUG_AT( GDKDFB_Window, " -> PIXMAP\n" ); - - gc = gdk_gc_new_with_values (GDK_DRAWABLE (impl), &values, - GDK_GC_FILL | GDK_GC_TILE | - GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN); - } - else - { - /* GDK_PARENT_RELATIVE_BG, but no pixmap, - get the color from the parent window. */ - - GdkGCValues values; - - values.foreground = relative_to->bg_color; - - D_DEBUG_AT( GDKDFB_Window, " -> COLOR\n" ); - - gc = gdk_gc_new_with_values (GDK_DRAWABLE (impl), &values, - GDK_GC_FOREGROUND); - } - - gdk_draw_rectangle (GDK_DRAWABLE (impl), - gc, TRUE, x, y, width, height); - - if (gc) - g_object_unref (gc); -} - static void gdk_window_directfb_raise (GdkWindow *window) { @@ -1890,20 +1854,16 @@ gdk_directfb_window_set_background (GdkWindow *window, static void gdk_directfb_window_set_back_pixmap (GdkWindow *window, - GdkPixmap *pixmap, - gboolean parent_relative) + GdkPixmap *pixmap) { GdkWindowObject *private; - GdkPixmap *old_pixmap; g_return_if_fail (GDK_IS_WINDOW (window)); - g_return_if_fail (pixmap == NULL || !parent_relative); - D_DEBUG_AT( GDKDFB_Window, "%s( %p, %p, %srelative )\n", __FUNCTION__, - window, pixmap, parent_relative ? "" : "not " ); + D_DEBUG_AT( GDKDFB_Window, "%s( %p, %p )\n", __FUNCTION__, + window, pixmap); private = GDK_WINDOW_OBJECT (window); - old_pixmap = private->bg_pixmap; if (private->bg_pixmap && private->bg_pixmap != GDK_PARENT_RELATIVE_BG && @@ -1912,7 +1872,7 @@ gdk_directfb_window_set_back_pixmap (GdkWindow *window, g_object_unref (private->bg_pixmap); } - if (parent_relative) + if (pixmap == GDK_PARENT_RELATIVE_BG) { private->bg_pixmap = GDK_PARENT_RELATIVE_BG; } @@ -2037,33 +1997,9 @@ _gdk_directfb_calc_abs (GdkWindow *window) } static gboolean -gdk_directfb_window_get_origin (GdkWindow *window, - gint *x, - gint *y) -{ - g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE); - - if (!GDK_WINDOW_DESTROYED (window)) - { - GdkDrawableImplDirectFB *impl; - - impl = GDK_DRAWABLE_IMPL_DIRECTFB (GDK_WINDOW_OBJECT (window)->impl); - - if (x) - *x = impl->abs_x; - if (y) - *y = impl->abs_y; - - return TRUE; - } - - return FALSE; -} - -gboolean -gdk_window_get_deskrelative_origin (GdkWindow *window, - gint *x, - gint *y) +gdk_directfb_window_get_deskrelative_origin (GdkWindow *window, + gint *x, + gint *y) { return gdk_window_get_origin (window, x, y); } @@ -2098,11 +2034,10 @@ gdk_window_get_root_origin (GdkWindow *window, } GdkWindow * -_gdk_windowing_window_get_pointer (GdkDisplay *display, - GdkWindow *window, - gint *x, - gint *y, - GdkModifierType *mask) +gdk_directfb_window_get_pointer_helper (GdkWindow *window, + gint *x, + gint *y, + GdkModifierType *mask) { GdkWindow *retval = NULL; gint rx, ry, wx, wy; @@ -2129,10 +2064,20 @@ _gdk_windowing_window_get_pointer (GdkDisplay *display, return retval; } +static gboolean +gdk_directfb_window_get_pointer (GdkWindow *window, + gint *x, + gint *y, + GdkModifierType *mask) +{ + return gdk_directfb_window_get_pointer_helper (window, x, y, mask) != NULL; +} + GdkWindow * _gdk_windowing_window_at_pointer (GdkDisplay *display, gint *win_x, - gint *win_y) + gint *win_y, + GdkModifierType *mask) { GdkWindow *retval; gint wx, wy; @@ -2154,6 +2099,26 @@ _gdk_windowing_window_at_pointer (GdkDisplay *display, if (win_y) *win_y = wy; + if (get_toplevel) + { + GdkWindowObject *w = (GdkWindowObject *)retval; + /* Requested toplevel, find it. */ + /* TODO: This can be implemented more efficient by never + recursing into children in the first place */ + if (w) + { + /* Convert to toplevel */ + while (w->parent != NULL && + w->parent->window_type != GDK_WINDOW_ROOT) + { + *win_x += w->x; + *win_y += w->y; + w = w->parent; + } + retval = (GdkWindow *)w; + } + } + return retval; } @@ -2164,13 +2129,16 @@ _gdk_windowing_get_pointer (GdkDisplay *display, gint *y, GdkModifierType *mask) { -(void)screen; -if(screen) { - *screen = gdk_display_get_default_screen (display); -} -_gdk_windowing_window_get_pointer (display, - _gdk_windowing_window_at_pointer(display,NULL,NULL),x,y,mask); + (void)screen; + if (screen) { + *screen = gdk_display_get_default_screen (display); + } + gdk_directfb_window_get_pointer (_gdk_windowing_window_at_pointer (display, + NULL, + NULL, + NULL), + x, y, mask); } static GdkEventMask @@ -2198,22 +2166,6 @@ gdk_directfb_window_set_events (GdkWindow *window, GDK_WINDOW_OBJECT (window)->event_mask = event_mask; } -static void -gdk_directfb_window_shape_combine_mask (GdkWindow *window, - GdkBitmap *mask, - gint x, - gint y) -{ -} - -void -gdk_window_input_shape_combine_mask (GdkWindow *window, - GdkBitmap *mask, - gint x, - gint y) -{ -} - static void gdk_directfb_window_shape_combine_region (GdkWindow *window, const GdkRegion *shape_region, @@ -2223,10 +2175,19 @@ gdk_directfb_window_shape_combine_region (GdkWindow *window, } void -gdk_window_input_shape_combine_region (GdkWindow *window, - const GdkRegion *shape_region, - gint offset_x, - gint offset_y) +gdk_directfb_window_input_shape_combine_region (GdkWindow *window, + const GdkRegion *shape_region, + gint offset_x, + gint offset_y) +{ +} + +static void +gdk_directfb_window_queue_translation (GdkWindow *window, + GdkGC *gc, + GdkRegion *region, + gint dx, + gint dy) { } @@ -2542,26 +2503,6 @@ gdk_window_set_functions (GdkWindow *window, g_message("unimplemented %s", __FUNCTION__); } -static void -gdk_directfb_window_set_child_shapes (GdkWindow *window) -{ -} - -static void -gdk_directfb_window_merge_child_shapes (GdkWindow *window) -{ -} - -void -gdk_window_set_child_input_shapes (GdkWindow *window) -{ -} - -void -gdk_window_merge_child_input_shapes (GdkWindow *window) -{ -} - static gboolean gdk_directfb_window_set_static_gravities (GdkWindow *window, gboolean use_static) @@ -2747,6 +2688,7 @@ gdk_window_foreign_new_for_display (GdkDisplay* display,GdkNativeWindow anid) private->impl = g_object_new (_gdk_window_impl_get_type (), NULL); private->parent = parent_private; private->window_type = GDK_WINDOW_TOPLEVEL; + private->viewable = TRUE; impl = GDK_WINDOW_IMPL_DIRECTFB (private->impl); impl->drawable.wrapper = GDK_DRAWABLE (window); @@ -2903,159 +2845,15 @@ gdk_window_set_urgency_hint (GdkWindow *window, } -static void -gdk_window_impl_directfb_invalidate_maybe_recurse (GdkPaintable *paintable, - const GdkRegion *region, - gboolean (*child_func) (GdkWindow *, gpointer), - gpointer user_data) -{ - GdkWindow *window; - GdkWindowObject *private; - GdkWindowImplDirectFB *wimpl; - GdkDrawableImplDirectFB *impl; - - wimpl = GDK_WINDOW_IMPL_DIRECTFB (paintable); - impl = (GdkDrawableImplDirectFB *)wimpl; - window = wimpl->gdkWindow; - private = (GdkWindowObject *)window; - - GdkRegion visible_region; - GList *tmp_list; - - g_return_if_fail (window != NULL); - g_return_if_fail (GDK_IS_WINDOW (window)); - - if (GDK_WINDOW_DESTROYED (window)) - return; - - if (private->input_only || !GDK_WINDOW_IS_MAPPED (window)) - return; - - temp_region_init_rectangle_vals( &visible_region, 0, 0, impl->width, impl->height ); - gdk_region_intersect (&visible_region, region); - - tmp_list = private->children; - while (tmp_list) - { - GdkWindowObject *child = tmp_list->data; - GdkDrawableImplDirectFB *cimpl = (GdkDrawableImplDirectFB *) child->impl; - - if (!child->input_only) - { - GdkRegion child_region; - - temp_region_init_rectangle_vals( &child_region, child->x, child->y, cimpl->width, cimpl->height ); - - /* remove child area from the invalid area of the parent */ - if (GDK_WINDOW_IS_MAPPED (child) && !child->shaped) - gdk_region_subtract (&visible_region, &child_region); - - if (child_func && (*child_func) ((GdkWindow *)child, user_data)) - { - gdk_region_intersect (&child_region, region); - gdk_region_offset (&child_region, - child->x, - child->y); - - gdk_window_invalidate_maybe_recurse ((GdkWindow *)child, - &child_region, child_func, user_data); - } - - temp_region_deinit( &child_region ); - } - - tmp_list = tmp_list->next; - } - - if (!gdk_region_empty (&visible_region)) - { - - if (private->update_area) - { - gdk_region_union (private->update_area, &visible_region); - } - else - { - update_windows = g_slist_prepend (update_windows, window); - private->update_area = gdk_region_copy (&visible_region); - gdk_window_schedule_update (window); - } - } - - temp_region_deinit( &visible_region ); -} - - -static void -gdk_window_impl_directfb_process_updates (GdkPaintable *paintable, - gboolean update_children) -{ - GdkWindowImplDirectFB *wimpl; - GdkDrawableImplDirectFB *impl; - GdkWindow *window; - GdkWindowObject *private; - GdkRegion *update_area; - - wimpl = GDK_WINDOW_IMPL_DIRECTFB (paintable); - impl = (GdkDrawableImplDirectFB *)wimpl; - window = wimpl->gdkWindow; - private = (GdkWindowObject *)window; - - D_DEBUG_AT( GDKDFB_Paintable, "%s( %p, %schildren )\n", __FUNCTION__, - paintable, update_children ? "update " : "no " ); - - /* If an update got queued during update processing, we can get a - * window in the update queue that has an empty update_area. - * just ignore it. - */ - if (!private->update_area) - return; - - update_area = private->update_area; - private->update_area = NULL; - - D_DEBUG_AT( GDKDFB_Paintable, " -> update area %4d,%4d-%4dx%4d\n", - GDKDFB_RECTANGLE_VALS_FROM_BOX( &update_area->extents ) ); - - if (_gdk_event_func && gdk_window_is_viewable (window)) - { - GdkRegion *expose_region = update_area; - GdkRegion window_region; - - temp_region_init_rectangle_vals( &window_region, 0, 0, impl->width, impl->height ); - gdk_region_intersect( expose_region, &window_region ); - temp_region_deinit (&window_region); - - if (!gdk_region_empty (expose_region) && (private->event_mask & GDK_EXPOSURE_MASK)) - { - GdkEvent event; - - event.expose.type = GDK_EXPOSE; - event.expose.window = g_object_ref (window); - event.expose.send_event = FALSE; - event.expose.count = 0; - event.expose.region = expose_region; - gdk_region_get_clipbox (expose_region, &event.expose.area); - (*_gdk_event_func) (&event, _gdk_event_data); - - g_object_unref (window); - } - - if (expose_region != update_area) - gdk_region_destroy (expose_region); - } - - gdk_region_destroy (update_area); -} - - static void gdk_window_impl_directfb_begin_paint_region (GdkPaintable *paintable, + GdkWindow *window, const GdkRegion *region) { GdkDrawableImplDirectFB *impl; GdkWindowImplDirectFB *wimpl; gint i; - g_assert (region != NULL ); wimpl = GDK_WINDOW_IMPL_DIRECTFB (paintable); impl = (GdkDrawableImplDirectFB *)wimpl; @@ -3194,19 +2992,56 @@ gdk_window_impl_directfb_end_paint (GdkPaintable *paintable) D_DEBUG_AT( GDKDFB_Window, " -> depth is still %d\n", impl->paint_depth ); } +GdkRegion * +_gdk_windowing_get_shape_for_mask (GdkBitmap *mask) +{ + return NULL; +} + +GdkRegion * +_gdk_windowing_window_get_shape (GdkWindow *window) +{ + return NULL; +} + +gulong +_gdk_windowing_window_get_next_serial (GdkDisplay *display) +{ + return 0; +} + +GdkRegion * +_gdk_windowing_window_get_input_shape (GdkWindow *window) +{ + return NULL; +} + +void +_gdk_windowing_before_process_all_updates (void) +{ +} + +void +_gdk_windowing_after_process_all_updates (void) +{ +} + +void +_gdk_windowing_window_process_updates_recurse (GdkWindow *window, + GdkRegion *region) +{ + _gdk_window_process_updates_recurse (window, region); +} static void gdk_window_impl_directfb_paintable_init (GdkPaintableIface *iface) { iface->begin_paint_region = gdk_window_impl_directfb_begin_paint_region; iface->end_paint = gdk_window_impl_directfb_end_paint; - - iface->invalidate_maybe_recurse = gdk_window_impl_directfb_invalidate_maybe_recurse; - iface->process_updates = gdk_window_impl_directfb_process_updates; } void -gdk_window_beep (GdkWindow *window) +_gdk_windowing_window_beep (GdkWindow *window) { gdk_display_beep (gdk_display_get_default()); } @@ -3239,32 +3074,49 @@ _gdk_windowing_window_set_composited (GdkWindow *window, { } +static gint +gdk_directfb_window_get_root_coords (GdkWindow *window, + gint x, + gint y, + gint *root_x, + gint *root_y) +{ + /* TODO */ + return 1; +} + +static gboolean +gdk_directfb_window_queue_antiexpose (GdkWindow *window, + GdkRegion *area) +{ + return FALSE; +} + static void gdk_window_impl_iface_init (GdkWindowImplIface *iface) { iface->show = gdk_directfb_window_show; iface->hide = gdk_directfb_window_hide; iface->withdraw = gdk_directfb_window_withdraw; + iface->set_events = gdk_directfb_window_set_events; + iface->get_events = gdk_directfb_window_get_events; iface->raise = gdk_window_directfb_raise; iface->lower = gdk_window_directfb_lower; iface->move_resize = gdk_directfb_window_move_resize; - iface->move_region = _gdk_directfb_window_move_region; - iface->scroll = _gdk_directfb_window_scroll; - iface->clear_area = gdk_directfb_window_clear_area; iface->set_background = gdk_directfb_window_set_background; iface->set_back_pixmap = gdk_directfb_window_set_back_pixmap; - iface->get_events = gdk_directfb_window_get_events; - iface->set_events = gdk_directfb_window_set_events; iface->reparent = gdk_directfb_window_reparent; iface->set_cursor = gdk_directfb_window_set_cursor; iface->get_geometry = gdk_directfb_window_get_geometry; - iface->get_origin = gdk_directfb_window_get_origin; - iface->get_offsets = _gdk_directfb_window_get_offsets; - iface->shape_combine_mask = gdk_directfb_window_shape_combine_mask; + iface->get_root_coords = gdk_directfb_window_get_root_coords; + iface->get_pointer = gdk_directfb_window_get_pointer; + iface->get_deskrelative_origin = gdk_directfb_window_get_deskrelative_origin; iface->shape_combine_region = gdk_directfb_window_shape_combine_region; - iface->set_child_shapes = gdk_directfb_window_set_child_shapes; - iface->merge_child_shapes = gdk_directfb_window_merge_child_shapes; + iface->input_shape_combine_region = gdk_directfb_window_input_shape_combine_region; iface->set_static_gravities = gdk_directfb_window_set_static_gravities; + iface->queue_antiexpose = gdk_directfb_window_queue_antiexpose; + iface->queue_translation = gdk_directfb_window_queue_translation; + iface->destroy = gdk_directfb_window_destroy; } #define __GDK_WINDOW_X11_C__ diff --git a/gdk/gdk.c b/gdk/gdk.c index da5d6335c2..5dd2fae952 100644 --- a/gdk/gdk.c +++ b/gdk/gdk.c @@ -206,6 +206,14 @@ gdk_pre_parse_libgtk_only (void) } #endif /* G_ENABLE_DEBUG */ + if (getenv ("GDK_NATIVE_WINDOWS")) + { + _gdk_native_windows = TRUE; + /* Ensure that this is not propagated + to spawned applications */ + g_unsetenv ("GDK_NATIVE_WINDOWS"); + } + g_type_init (); /* Do any setup particular to the windowing system diff --git a/gdk/gdk.symbols b/gdk/gdk.symbols index cfb54c2023..6e25f878a2 100644 --- a/gdk/gdk.symbols +++ b/gdk/gdk.symbols @@ -22,7 +22,9 @@ #if IN_HEADER(__GDK_EVENTS_H__) #if IN_FILE(__GDK_EVENTS_X11_C__) gdk_add_client_message_filter +#ifndef GDK_DISABLE_DEPRECATED gdk_event_get_graphics_expose +#endif gdk_events_pending #endif #endif @@ -69,9 +71,6 @@ gdk_get_use_xshm gdk_set_use_xshm #endif gdk_keyboard_grab -gdk_keyboard_grab_info_libgtk_only -gdk_pointer_grab -gdk_pointer_grab_info_libgtk_only #endif #endif @@ -85,6 +84,9 @@ gdk_pointer_is_grabbed gdk_pointer_ungrab gdk_event_send_client_message gdk_event_send_clientmessage_toall +gdk_keyboard_grab_info_libgtk_only +gdk_pointer_grab_info_libgtk_only +gdk_display_pointer_is_grabbed #endif #endif @@ -254,12 +256,6 @@ gdk_visual_type_get_type G_GNUC_CONST #endif #endif -#if IN_HEADER(__GDK_PIXMAP_H__) -#if IN_FILE(__GDK_PIXMAP_X11_C__) -gdk_bitmap_create_from_data -#endif -#endif - #if IN_HEADER(__GDK_FONT_H__) #if IN_FILE(__GDK_FONT_C__) #ifndef GDK_DISABLE_DEPRECATED @@ -305,6 +301,7 @@ gdk_fontset_load_for_display #if IN_HEADER(__GDK_CAIRO_H__) #if IN_FILE(__GDK_CAIRO_C__) gdk_cairo_create +gdk_cairo_reset_clip gdk_cairo_set_source_color gdk_cairo_set_source_pixbuf gdk_cairo_set_source_pixmap @@ -466,7 +463,6 @@ gdk_display_get_default_screen gdk_display_get_name gdk_display_get_n_screens gdk_display_get_screen -gdk_display_pointer_is_grabbed gdk_display_pointer_ungrab gdk_display_keyboard_ungrab gdk_display_open @@ -657,6 +653,7 @@ gdk_window_get_events gdk_window_set_events gdk_window_raise gdk_window_lower +gdk_window_restack gdk_window_move gdk_window_resize gdk_window_move_resize @@ -665,12 +662,19 @@ gdk_window_move_region gdk_window_set_background gdk_window_set_back_pixmap gdk_window_set_cursor +gdk_window_get_cursor gdk_window_get_geometry gdk_window_get_origin +gdk_window_get_root_coords +gdk_window_get_deskrelative_origin gdk_window_shape_combine_mask gdk_window_shape_combine_region gdk_window_set_child_shapes gdk_window_merge_child_shapes +gdk_window_input_shape_combine_mask +gdk_window_input_shape_combine_region +gdk_window_set_child_input_shapes +gdk_window_merge_child_input_shapes gdk_window_set_static_gravities gdk_window_reparent gdk_window_add_filter @@ -683,6 +687,7 @@ gdk_window_clear_area_e gdk_window_constrain_size gdk_window_destroy gdk_window_end_paint +gdk_window_flush gdk_window_foreign_new gdk_window_freeze_toplevel_updates_libgtk_only gdk_window_freeze_updates @@ -699,6 +704,7 @@ gdk_window_get_toplevels gdk_window_get_update_area gdk_window_get_user_data gdk_window_get_window_type +gdk_window_is_destroyed gdk_window_invalidate_maybe_recurse gdk_window_invalidate_rect gdk_window_invalidate_region @@ -716,6 +722,24 @@ gdk_window_set_user_data gdk_window_thaw_toplevel_updates_libgtk_only gdk_window_thaw_updates gdk_window_set_composited +gdk_pointer_grab +gdk_window_beep +gdk_window_geometry_changed +gdk_window_ensure_native +#endif +#endif + +#if IN_HEADER(__GDK_WINDOW_H__) +#if IN_FILE(__GDK_OFFSCREEN_WINDOW_C__) +gdk_offscreen_window_get_pixmap +gdk_offscreen_window_set_embedder +gdk_offscreen_window_get_embedder +#endif +#endif + +#if IN_HEADER(__GDK_INTERNALS_H__) +#if IN_FILE(__GDK_OFFSCREEN_WINDOW_C__) +gdk_offscreen_window_get_type G_GNUC_CONST #endif #endif @@ -733,7 +757,6 @@ gdk_window_lookup gdk_window_lookup_for_display #ifndef GDK_DISABLE_DEPRECATED gdk_window_set_hints -gdk_window_get_deskrelative_origin #endif gdk_window_get_type_hint gdk_window_set_type_hint @@ -748,15 +771,12 @@ gdk_window_set_startup_id gdk_window_set_transient_for gdk_window_get_root_origin gdk_window_get_frame_extents -gdk_window_input_shape_combine_mask -gdk_window_input_shape_combine_region gdk_window_set_override_redirect gdk_window_set_accept_focus gdk_window_set_focus_on_map gdk_window_set_icon_list gdk_window_set_icon gdk_window_set_icon_name -gdk_window_beep gdk_window_set_opacity gdk_window_iconify gdk_window_deiconify @@ -773,8 +793,6 @@ gdk_window_set_group gdk_window_get_decorations gdk_window_set_decorations gdk_window_set_functions -gdk_window_set_child_input_shapes -gdk_window_merge_child_input_shapes gdk_window_begin_move_drag gdk_window_begin_resize_drag gdk_window_enable_synchronized_configure @@ -925,23 +943,24 @@ gdk_pixbuf_render_to_drawable_alpha #if IN_HEADER(__GDK_PIXMAP_H__) #if IN_FILE(__GDK_PIXMAP_C__) +gdk_bitmap_create_from_data gdk_pixmap_colormap_create_from_xpm +gdk_pixmap_create_from_data gdk_pixmap_create_from_xpm gdk_pixmap_colormap_create_from_xpm_d gdk_pixmap_create_from_xpm_d gdk_pixmap_get_type G_GNUC_CONST +gdk_pixmap_new #endif #endif #if IN_HEADER(__GDK_PIXMAP_H__) #if IN_FILE(__GDK_PIXMAP_X11_C__) -gdk_pixmap_create_from_data gdk_pixmap_foreign_new gdk_pixmap_foreign_new_for_display gdk_pixmap_foreign_new_for_screen gdk_pixmap_lookup gdk_pixmap_lookup_for_display -gdk_pixmap_new #endif #endif @@ -951,6 +970,7 @@ gdk_region_copy gdk_region_destroy gdk_region_empty gdk_region_equal +gdk_region_rect_equal gdk_region_get_clipbox gdk_region_get_rectangles gdk_region_intersect @@ -1202,6 +1222,8 @@ gdk_x11_display_get_startup_notification_id #if IN_FILE(__GDK_DRAWABLE_X11_C__) gdk_x11_drawable_get_xdisplay gdk_x11_drawable_get_xid +gdk_x11_window_get_drawable_impl +gdk_x11_pixmap_get_drawable_impl #endif #if IN_FILE(__GDK_FONT_X11_C__) diff --git a/gdk/gdkcairo.c b/gdk/gdkcairo.c index 6e83f53a37..ef8ec25627 100644 --- a/gdk/gdkcairo.c +++ b/gdk/gdkcairo.c @@ -50,11 +50,43 @@ gdk_cairo_create (GdkDrawable *drawable) surface = _gdk_drawable_ref_cairo_surface (drawable); cr = cairo_create (surface); + + if (GDK_DRAWABLE_GET_CLASS (drawable)->set_cairo_clip) + GDK_DRAWABLE_GET_CLASS (drawable)->set_cairo_clip (drawable, cr); + cairo_surface_destroy (surface); return cr; } +/** + * gdk_cairo_reset_clip: + * @cr: a #cairo_t + * @drawable: a #GdkDrawable + * + * Resets the clip region for a Cairo context created by gdk_cairo_create(). + * + * This resets the clip region to the "empty" state for the given drawable. + * This is required for non-native windows since a direct call to + * cairo_reset_clip() would unset the clip region inherited from the + * drawable (i.e. the window clip region), and thus let you e.g. + * draw outside your window. + * + * This is rarely needed though, since most code just create a new cairo_t + * using gdk_cairo_create() each time they want to draw something. + * + * Since: 2.18 + **/ +void +gdk_cairo_reset_clip (cairo_t *cr, + GdkDrawable *drawable) +{ + cairo_reset_clip (cr); + + if (GDK_DRAWABLE_GET_CLASS (drawable)->set_cairo_clip) + GDK_DRAWABLE_GET_CLASS (drawable)->set_cairo_clip (drawable, cr); +} + /** * gdk_cairo_set_source_color: * @cr: a #cairo_t diff --git a/gdk/gdkcairo.h b/gdk/gdkcairo.h index 70d79de882..8bddd48c2a 100644 --- a/gdk/gdkcairo.h +++ b/gdk/gdkcairo.h @@ -31,6 +31,8 @@ G_BEGIN_DECLS cairo_t *gdk_cairo_create (GdkDrawable *drawable); +void gdk_cairo_reset_clip (cairo_t *cr, + GdkDrawable *drawable); void gdk_cairo_set_source_color (cairo_t *cr, const GdkColor *color); diff --git a/gdk/gdkdisplay.c b/gdk/gdkdisplay.c index 9417c4e947..c2064bad67 100644 --- a/gdk/gdkdisplay.c +++ b/gdk/gdkdisplay.c @@ -22,9 +22,11 @@ */ #include "config.h" +#include #include #include "gdk.h" /* gdk_event_send_client_message() */ #include "gdkdisplay.h" +#include "gdkwindowimpl.h" #include "gdkinternals.h" #include "gdkmarshalers.h" #include "gdkscreen.h" @@ -60,6 +62,14 @@ static GdkWindow* singlehead_default_window_get_pointer (GdkWindow *window static GdkWindow* singlehead_default_window_at_pointer (GdkScreen *screen, gint *win_x, gint *win_y); +static GdkWindow *gdk_window_real_window_get_pointer (GdkDisplay *display, + GdkWindow *window, + gint *x, + gint *y, + GdkModifierType *mask); +static GdkWindow *gdk_display_real_get_window_at_pointer (GdkDisplay *display, + gint *win_x, + gint *win_y); static guint signals[LAST_SIGNAL] = { 0 }; @@ -67,8 +77,8 @@ static char *gdk_sm_client_id; static const GdkDisplayPointerHooks default_pointer_hooks = { _gdk_windowing_get_pointer, - _gdk_windowing_window_get_pointer, - _gdk_windowing_window_at_pointer + gdk_window_real_window_get_pointer, + gdk_display_real_get_window_at_pointer }; static const GdkDisplayPointerHooks singlehead_pointer_hooks = { @@ -110,7 +120,7 @@ gdk_display_class_init (GdkDisplayClass *class) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GdkDisplayClass, closed), NULL, NULL, - gdk_marshal_VOID__BOOLEAN, + _gdk_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN); @@ -434,6 +444,25 @@ _gdk_get_sm_client_id (void) return gdk_sm_client_id; } +void +_gdk_display_enable_motion_hints (GdkDisplay *display) +{ + gulong serial; + + if (display->pointer_info.motion_hint_serial != 0) + { + serial = _gdk_windowing_window_get_next_serial (display); + /* We might not actually generate the next request, so + make sure this triggers always, this may cause it to + trigger slightly too early, but this is just a hint + anyway. */ + if (serial > 0) + serial--; + if (serial < display->pointer_info.motion_hint_serial) + display->pointer_info.motion_hint_serial = serial; + } +} + /** * gdk_display_get_pointer: * @display: a #GdkDisplay @@ -473,6 +502,68 @@ gdk_display_get_pointer (GdkDisplay *display, *mask = tmp_mask; } +static GdkWindow * +gdk_display_real_get_window_at_pointer (GdkDisplay *display, + gint *win_x, + gint *win_y) +{ + GdkWindow *window; + gint x, y; + + window = _gdk_windowing_window_at_pointer (display, &x, &y, NULL, FALSE); + + /* This might need corrections, as the native window returned + may contain client side children */ + if (window) + { + double xx, yy; + + window = _gdk_window_find_descendant_at (window, + x, y, + &xx, &yy); + x = floor (xx + 0.5); + y = floor (yy + 0.5); + } + + *win_x = x; + *win_y = y; + + return window; +} + +static GdkWindow * +gdk_window_real_window_get_pointer (GdkDisplay *display, + GdkWindow *window, + gint *x, + gint *y, + GdkModifierType *mask) +{ + GdkWindowObject *private; + gint tmpx, tmpy; + GdkModifierType tmp_mask; + gboolean normal_child; + + private = (GdkWindowObject *) window; + + normal_child = GDK_WINDOW_IMPL_GET_IFACE (private->impl)->get_pointer (window, + &tmpx, &tmpy, + &tmp_mask); + /* We got the coords on the impl, convert to the window */ + tmpx -= private->abs_x; + tmpy -= private->abs_y; + + if (x) + *x = tmpx; + if (y) + *y = tmpy; + if (mask) + *mask = tmp_mask; + + if (normal_child) + return _gdk_window_find_child_at (window, tmpx, tmpy); + return NULL; +} + /** * gdk_display_get_window_at_pointer: * @display: a #GdkDisplay @@ -586,8 +677,8 @@ singlehead_default_window_get_pointer (GdkWindow *window, gint *y, GdkModifierType *mask) { - return _gdk_windowing_window_get_pointer (gdk_drawable_get_display (window), - window, x, y, mask); + return gdk_window_real_window_get_pointer (gdk_drawable_get_display (window), + window, x, y, mask); } static GdkWindow* @@ -595,8 +686,8 @@ singlehead_default_window_at_pointer (GdkScreen *screen, gint *win_x, gint *win_y) { - return _gdk_windowing_window_at_pointer (gdk_screen_get_display (screen), - win_x, win_y); + return gdk_display_real_get_window_at_pointer (gdk_screen_get_display (screen), + win_x, win_y); } /** @@ -632,5 +723,561 @@ gdk_set_pointer_hooks (const GdkPointerHooks *new_hooks) return (GdkPointerHooks *)result; } +static void +generate_grab_broken_event (GdkWindow *window, + gboolean keyboard, + gboolean implicit, + GdkWindow *grab_window) +{ + g_return_if_fail (window != NULL); + + if (!GDK_WINDOW_DESTROYED (window)) + { + GdkEvent event; + event.type = GDK_GRAB_BROKEN; + event.grab_broken.window = window; + event.grab_broken.send_event = 0; + event.grab_broken.keyboard = keyboard; + event.grab_broken.implicit = implicit; + event.grab_broken.grab_window = grab_window; + gdk_event_put (&event); + } +} + +GdkPointerGrabInfo * +_gdk_display_get_last_pointer_grab (GdkDisplay *display) +{ + GList *l; + + l = g_list_last (display->pointer_grabs); + + if (l == NULL) + return NULL; + else + return (GdkPointerGrabInfo *)l->data; +} + + +GdkPointerGrabInfo * +_gdk_display_add_pointer_grab (GdkDisplay *display, + GdkWindow *window, + GdkWindow *native_window, + gboolean owner_events, + GdkEventMask event_mask, + unsigned long serial_start, + guint32 time, + gboolean implicit) +{ + GdkPointerGrabInfo *info, *other_info; + GList *l; + + info = g_new0 (GdkPointerGrabInfo, 1); + + info->window = g_object_ref (window); + info->native_window = g_object_ref (native_window); + info->serial_start = serial_start; + info->serial_end = G_MAXULONG; + info->owner_events = owner_events; + info->event_mask = event_mask; + info->time = time; + info->implicit = implicit; + + /* Find the first grab that has a larger start time (if any) and insert + * before that. I.E we insert after already existing grabs with same + * start time */ + for (l = display->pointer_grabs; l != NULL; l = l->next) + { + other_info = l->data; + + if (info->serial_start < other_info->serial_start) + break; + } + display->pointer_grabs = + g_list_insert_before (display->pointer_grabs, l, info); + + /* Make sure the new grab end before next grab */ + if (l) + { + other_info = l->data; + info->serial_end = other_info->serial_start; + } + + /* Find any previous grab and update its end time */ + l = g_list_find (display->pointer_grabs, info); + l = l->prev; + if (l) + { + other_info = l->data; + other_info->serial_end = serial_start; + } + + return info; +} + +static void +free_pointer_grab (GdkPointerGrabInfo *info) +{ + g_object_unref (info->window); + g_object_unref (info->native_window); + g_free (info); +} + +/* _gdk_synthesize_crossing_events only works inside one toplevel. + This function splits things into two calls if needed, converting the + coordinates to the right toplevel */ +static void +synthesize_crossing_events (GdkDisplay *display, + GdkWindow *src_window, + GdkWindow *dest_window, + GdkCrossingMode crossing_mode, + guint32 time, + gulong serial) +{ + GdkWindow *src_toplevel, *dest_toplevel; + GdkModifierType state; + int x, y; + + /* We use the native crossing events if all native */ + if (_gdk_native_windows) + return; + + if (src_window) + src_toplevel = gdk_window_get_toplevel (src_window); + else + src_toplevel = NULL; + if (dest_window) + dest_toplevel = gdk_window_get_toplevel (dest_window); + else + dest_toplevel = NULL; + + if (src_toplevel == NULL && dest_toplevel == NULL) + return; + + if (src_toplevel == NULL || + src_toplevel == dest_toplevel) + { + /* Same toplevels */ + gdk_window_get_pointer (dest_toplevel, + &x, &y, &state); + _gdk_synthesize_crossing_events (display, + src_window, + dest_window, + crossing_mode, + x, y, state, + time, + NULL, + serial, FALSE); + } + else if (dest_toplevel == NULL) + { + gdk_window_get_pointer (src_toplevel, + &x, &y, &state); + _gdk_synthesize_crossing_events (display, + src_window, + NULL, + crossing_mode, + x, y, state, + time, + NULL, + serial, FALSE); + } + else + { + /* Different toplevels */ + gdk_window_get_pointer (src_toplevel, + &x, &y, &state); + _gdk_synthesize_crossing_events (display, + src_window, + NULL, + crossing_mode, + x, y, state, + time, + NULL, + serial, FALSE); + gdk_window_get_pointer (dest_toplevel, + &x, &y, &state); + _gdk_synthesize_crossing_events (display, + NULL, + dest_window, + crossing_mode, + x, y, state, + time, + NULL, + serial, FALSE); + } +} + +static GdkWindow * +get_current_toplevel (GdkDisplay *display, + int *x_out, int *y_out, + GdkModifierType *state_out) +{ + GdkWindow *pointer_window; + int x, y; + GdkModifierType state; + + pointer_window = _gdk_windowing_window_at_pointer (display, &x, &y, &state, TRUE); + if (pointer_window != NULL && + (GDK_WINDOW_DESTROYED (pointer_window) || + GDK_WINDOW_TYPE (pointer_window) == GDK_WINDOW_ROOT || + GDK_WINDOW_TYPE (pointer_window) == GDK_WINDOW_FOREIGN)) + pointer_window = NULL; + + *x_out = x; + *y_out = y; + *state_out = state; + return pointer_window; +} + +static void +switch_to_pointer_grab (GdkDisplay *display, + GdkPointerGrabInfo *grab, + GdkPointerGrabInfo *last_grab, + guint32 time, + gulong serial) +{ + GdkWindow *src_window, *pointer_window, *new_toplevel; + GList *old_grabs; + GdkModifierType state; + int x, y; + + /* Temporarily unset pointer to make sure we send the crossing events below */ + old_grabs = display->pointer_grabs; + display->pointer_grabs = NULL; + + if (grab) + { + /* New grab is in effect */ + + /* We need to generate crossing events for the grab. + * However, there are never any crossing events for implicit grabs + * TODO: ... Actually, this could happen if the pointer window + * doesn't have button mask so a parent gets the event... + */ + if (!grab->implicit) + { + /* We send GRAB crossing events from the window under the pointer to the + grab window. Except if there is an old grab then we start from that */ + if (last_grab) + src_window = last_grab->window; + else + src_window = display->pointer_info.window_under_pointer; + + if (src_window != grab->window) + { + synthesize_crossing_events (display, + src_window, grab->window, + GDK_CROSSING_GRAB, time, serial); + } + + /* !owner_event Grabbing a window that we're not inside, current status is + now NULL (i.e. outside grabbed window) */ + if (!grab->owner_events && display->pointer_info.window_under_pointer != grab->window) + _gdk_display_set_window_under_pointer (display, NULL); + } + + grab->activated = TRUE; + } + + if (last_grab) + { + new_toplevel = NULL; + + if (grab == NULL /* ungrab */ || + (!last_grab->owner_events && grab->owner_events) /* switched to owner_events */ ) + { + /* We force check what window we're in, and update the toplevel_under_pointer info, + * as that won't get told of this change with toplevel enter events. + */ + if (display->pointer_info.toplevel_under_pointer) + g_object_unref (display->pointer_info.toplevel_under_pointer); + display->pointer_info.toplevel_under_pointer = NULL; + + new_toplevel = get_current_toplevel (display, &x, &y, &state); + if (new_toplevel) + { + /* w is now toplevel and x,y in toplevel coords */ + display->pointer_info.toplevel_under_pointer = g_object_ref (new_toplevel); + display->pointer_info.toplevel_x = x; + display->pointer_info.toplevel_y = y; + display->pointer_info.state = state; + } + } + + if (grab == NULL) /* Ungrabbed, send events */ + { + pointer_window = NULL; + if (new_toplevel) + { + /* Find (possibly virtual) child window */ + pointer_window = + _gdk_window_find_descendant_at (new_toplevel, + x, y, + NULL, NULL); + } + + if (pointer_window != last_grab->window) + synthesize_crossing_events (display, + last_grab->window, pointer_window, + GDK_CROSSING_UNGRAB, time, serial); + + /* We're now ungrabbed, update the window_under_pointer */ + _gdk_display_set_window_under_pointer (display, pointer_window); + } + } + + display->pointer_grabs = old_grabs; + +} + +void +_gdk_display_pointer_grab_update (GdkDisplay *display, + gulong current_serial) +{ + GdkPointerGrabInfo *current_grab, *next_grab; + guint32 time; + + time = display->last_event_time; + + while (display->pointer_grabs != NULL) + { + current_grab = display->pointer_grabs->data; + + if (current_grab->serial_start > current_serial) + return; /* Hasn't started yet */ + + if (current_grab->serial_end > current_serial) + { + /* This one hasn't ended yet. + its the currently active one or scheduled to be active */ + + if (!current_grab->activated) + switch_to_pointer_grab (display, current_grab, NULL, time, current_serial); + + break; + } + + + next_grab = NULL; + if (display->pointer_grabs->next) + { + /* This is the next active grab */ + next_grab = display->pointer_grabs->next->data; + + if (next_grab->serial_start > current_serial) + next_grab = NULL; /* Actually its not yet active */ + } + + if ((next_grab == NULL && current_grab->implicit_ungrab) || + (next_grab != NULL && current_grab->window != next_grab->window)) + generate_grab_broken_event (GDK_WINDOW (current_grab->window), + FALSE, current_grab->implicit, + next_grab? next_grab->window : NULL); + + /* Remove old grab */ + display->pointer_grabs = + g_list_delete_link (display->pointer_grabs, + display->pointer_grabs); + + switch_to_pointer_grab (display, + next_grab, current_grab, + time, current_serial); + + free_pointer_grab (current_grab); + } +} + +static GList * +find_pointer_grab (GdkDisplay *display, + gulong serial) +{ + GdkPointerGrabInfo *grab; + GList *l; + + for (l = display->pointer_grabs; l != NULL; l = l->next) + { + grab = l->data; + + if (serial >= grab->serial_start && serial < grab->serial_end) + return l; + } + + return NULL; +} + + + +GdkPointerGrabInfo * +_gdk_display_has_pointer_grab (GdkDisplay *display, + gulong serial) +{ + GList *l; + + l = find_pointer_grab (display, serial); + if (l) + return l->data; + + return NULL; +} + +/* Returns true if last grab was ended + * If if_child is non-NULL, end the grab only if the grabbed + * window is the same as if_child or a descendant of it */ +gboolean +_gdk_display_end_pointer_grab (GdkDisplay *display, + gulong serial, + GdkWindow *if_child, + gboolean implicit) +{ + GdkPointerGrabInfo *grab; + GList *l; + + l = find_pointer_grab (display, serial); + + if (l == NULL) + return FALSE; + + grab = l->data; + if (grab && + (if_child == NULL || + _gdk_window_event_parent_of (if_child, grab->window))) + { + grab->serial_end = serial; + grab->implicit_ungrab = implicit; + return l->next == NULL; + } + + return FALSE; +} + +void +_gdk_display_set_has_keyboard_grab (GdkDisplay *display, + GdkWindow *window, + GdkWindow *native_window, + gboolean owner_events, + unsigned long serial, + guint32 time) +{ + if (display->keyboard_grab.window != NULL && + display->keyboard_grab.window != window) + generate_grab_broken_event (display->keyboard_grab.window, + TRUE, FALSE, window); + + display->keyboard_grab.window = window; + display->keyboard_grab.native_window = native_window; + display->keyboard_grab.owner_events = owner_events; + display->keyboard_grab.serial = serial; + display->keyboard_grab.time = time; +} + +void +_gdk_display_unset_has_keyboard_grab (GdkDisplay *display, + gboolean implicit) +{ + if (implicit) + generate_grab_broken_event (display->keyboard_grab.window, + TRUE, FALSE, NULL); + display->keyboard_grab.window = NULL; +} + +/** + * gdk_keyboard_grab_info_libgtk_only: + * @display: the display for which to get the grab information + * @grab_window: location to store current grab window + * @owner_events: location to store boolean indicating whether + * the @owner_events flag to gdk_keyboard_grab() was %TRUE. + * + * Determines information about the current keyboard grab. + * This is not public API and must not be used by applications. + * + * Return value: %TRUE if this application currently has the + * keyboard grabbed. + **/ +gboolean +gdk_keyboard_grab_info_libgtk_only (GdkDisplay *display, + GdkWindow **grab_window, + gboolean *owner_events) +{ + g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE); + + if (display->keyboard_grab.window) + { + if (grab_window) + *grab_window = display->keyboard_grab.window; + if (owner_events) + *owner_events = display->keyboard_grab.owner_events; + + return TRUE; + } + else + return FALSE; +} + +/** + * gdk_pointer_grab_info_libgtk_only: + * @display: the #GdkDisplay for which to get the grab information + * @grab_window: location to store current grab window + * @owner_events: location to store boolean indicating whether + * the @owner_events flag to gdk_pointer_grab() was %TRUE. + * + * Determines information about the current pointer grab. + * This is not public API and must not be used by applications. + * + * Return value: %TRUE if this application currently has the + * pointer grabbed. + **/ +gboolean +gdk_pointer_grab_info_libgtk_only (GdkDisplay *display, + GdkWindow **grab_window, + gboolean *owner_events) +{ + GdkPointerGrabInfo *info; + + g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE); + + /* What we're interested in is the steady state (ie last grab), + because we're interested e.g. if we grabbed so that we + can ungrab, even if our grab is not active just yet. */ + info = _gdk_display_get_last_pointer_grab (display); + + if (info) + { + if (grab_window) + *grab_window = info->window; + if (owner_events) + *owner_events = info->owner_events; + + return TRUE; + } + else + return FALSE; +} + + +/** + * gdk_display_pointer_is_grabbed: + * @display: a #GdkDisplay + * + * Test if the pointer is grabbed. + * + * Returns: %TRUE if an active X pointer grab is in effect + * + * Since: 2.2 + */ +gboolean +gdk_display_pointer_is_grabbed (GdkDisplay *display) +{ + GdkPointerGrabInfo *info; + + g_return_val_if_fail (GDK_IS_DISPLAY (display), TRUE); + + /* What we're interested in is the steady state (ie last grab), + because we're interested e.g. if we grabbed so that we + can ungrab, even if our grab is not active just yet. */ + info = _gdk_display_get_last_pointer_grab (display); + + return (info && !info->implicit); +} + #define __GDK_DISPLAY_C__ #include "gdkaliasdef.c" diff --git a/gdk/gdkdisplay.h b/gdk/gdkdisplay.h index 04bf1831bb..2838d44a02 100644 --- a/gdk/gdkdisplay.h +++ b/gdk/gdkdisplay.h @@ -43,6 +43,33 @@ typedef struct _GdkDisplayPointerHooks GdkDisplayPointerHooks; #define GDK_IS_DISPLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_DISPLAY)) #define GDK_DISPLAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_DISPLAY, GdkDisplayClass)) +/* Tracks information about the keyboard grab on this display */ +typedef struct +{ + GdkWindow *window; + GdkWindow *native_window; + gulong serial; + gboolean owner_events; + guint32 time; +} GdkKeyboardGrabInfo; + +/* Tracks information about which window and position the pointer last was in. + * This is useful when we need to synthesize events later. + * Note that we track toplevel_under_pointer using enter/leave events, + * so in the case of a grab, either with owner_events==FALSE or with the + * pointer in no clients window the x/y coordinates may actually be outside + * the window. + */ +typedef struct +{ + GdkWindow *toplevel_under_pointer; /* The toplevel window with mouse inside, tracked via native events */ + GdkWindow *window_under_pointer; /* The window that last got sent a normal enter event */ + gdouble toplevel_x, toplevel_y; + guint32 state; + guint32 button; + gulong motion_hint_serial; /* 0 == didn't deliver hinted motion event */ +} GdkPointerWindowInfo; + struct _GdkDisplay { GObject parent_instance; @@ -64,10 +91,18 @@ struct _GdkDisplay const GdkDisplayPointerHooks *pointer_hooks; /* Current hooks for querying pointer */ guint closed : 1; /* Whether this display has been closed */ + guint ignore_core_events : 1; /* Don't send core motion and button event */ guint double_click_distance; /* Maximum distance between clicks in pixels */ gint button_x[2]; /* The last 2 button click positions. */ gint button_y[2]; + + GList *pointer_grabs; + GdkKeyboardGrabInfo keyboard_grab; + GdkPointerWindowInfo pointer_info; + + /* Last reported event time from server */ + guint32 last_event_time; }; struct _GdkDisplayClass diff --git a/gdk/gdkdisplaymanager.c b/gdk/gdkdisplaymanager.c index 72755a1b3f..0f9a094eb9 100644 --- a/gdk/gdkdisplaymanager.c +++ b/gdk/gdkdisplaymanager.c @@ -92,7 +92,7 @@ gdk_display_manager_class_init (GdkDisplayManagerClass *klass) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GdkDisplayManagerClass, display_opened), NULL, NULL, - gdk_marshal_VOID__OBJECT, + _gdk_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GDK_TYPE_DISPLAY); diff --git a/gdk/gdkdraw.c b/gdk/gdkdraw.c index 81e6e08390..829dd2ba61 100644 --- a/gdk/gdkdraw.c +++ b/gdk/gdkdraw.c @@ -61,6 +61,15 @@ static void gdk_drawable_real_draw_pixbuf (GdkDrawable *draw GdkRgbDither dither, gint x_dither, gint y_dither); +static void gdk_drawable_real_draw_drawable (GdkDrawable *drawable, + GdkGC *gc, + GdkDrawable *src, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height); G_DEFINE_ABSTRACT_TYPE (GdkDrawable, gdk_drawable, G_TYPE_OBJECT) @@ -74,6 +83,7 @@ gdk_drawable_class_init (GdkDrawableClass *klass) klass->get_clip_region = gdk_drawable_real_get_visible_region; klass->get_visible_region = gdk_drawable_real_get_visible_region; klass->draw_pixbuf = gdk_drawable_real_draw_pixbuf; + klass->draw_drawable = gdk_drawable_real_draw_drawable; } static void @@ -150,7 +160,8 @@ gdk_drawable_get_size (GdkDrawable *drawable, { g_return_if_fail (GDK_IS_DRAWABLE (drawable)); - GDK_DRAWABLE_GET_CLASS (drawable)->get_size (drawable, width, height); + if (GDK_DRAWABLE_GET_CLASS (drawable)->get_size != NULL) + GDK_DRAWABLE_GET_CLASS (drawable)->get_size (drawable, width, height); } /** @@ -652,13 +663,26 @@ gdk_draw_drawable (GdkDrawable *drawable, &composite_x_offset, &composite_y_offset); - - GDK_DRAWABLE_GET_CLASS (drawable)->draw_drawable (drawable, gc, composite, - xsrc - composite_x_offset, - ysrc - composite_y_offset, - xdest, ydest, - width, height); - + /* TODO: For non-native windows this may copy stuff from other overlapping + windows. We should clip that and (for windows with bg != None) clear that + area in the destination instead. */ + + if (GDK_DRAWABLE_GET_CLASS (drawable)->draw_drawable_with_src) + GDK_DRAWABLE_GET_CLASS (drawable)->draw_drawable_with_src (drawable, gc, + composite, + xsrc - composite_x_offset, + ysrc - composite_y_offset, + xdest, ydest, + width, height, + src); + else /* backwards compat for old out-of-tree implementations of GdkDrawable (are there any?) */ + GDK_DRAWABLE_GET_CLASS (drawable)->draw_drawable (drawable, gc, + composite, + xsrc - composite_x_offset, + ysrc - composite_y_offset, + xdest, ydest, + width, height); + g_object_unref (composite); } @@ -727,9 +751,6 @@ gdk_draw_image (GdkDrawable *drawable, * On older X servers, rendering pixbufs with an alpha channel involves round * trips to the X server, and may be somewhat slow. * - * The clip mask of @gc is ignored, but clip rectangles and clip regions work - * fine. - * * If GDK is built with the Sun mediaLib library, the gdk_draw_pixbuf * function is accelerated using mediaLib, which provides hardware * acceleration on Intel, AMD, and Sparc chipsets. If desired, mediaLib @@ -871,7 +892,7 @@ real_draw_glyphs (GdkDrawable *drawable, cairo_t *cr; cr = gdk_cairo_create (drawable); - _gdk_gc_update_context (gc, cr, NULL, NULL, TRUE); + _gdk_gc_update_context (gc, cr, NULL, NULL, TRUE, drawable); if (matrix) { @@ -995,7 +1016,7 @@ gdk_draw_trapezoids (GdkDrawable *drawable, g_return_if_fail (n_trapezoids == 0 || trapezoids != NULL); cr = gdk_cairo_create (drawable); - _gdk_gc_update_context (gc, cr, NULL, NULL, TRUE); + _gdk_gc_update_context (gc, cr, NULL, NULL, TRUE, drawable); for (i = 0; i < n_trapezoids; i++) { @@ -1185,7 +1206,7 @@ gdk_drawable_real_get_image (GdkDrawable *drawable, return gdk_drawable_copy_to_image (drawable, NULL, x, y, 0, 0, width, height); } -static GdkDrawable* +static GdkDrawable * gdk_drawable_real_get_composite_drawable (GdkDrawable *drawable, gint x, gint y, @@ -1484,6 +1505,31 @@ composite_565 (guchar *src_buf, } } +/* Implementation of the old vfunc in terms of the new one + in case someone calls it directly (which they shouldn't!) */ +static void +gdk_drawable_real_draw_drawable (GdkDrawable *drawable, + GdkGC *gc, + GdkDrawable *src, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height) +{ + GDK_DRAWABLE_GET_CLASS (drawable)->draw_drawable_with_src (drawable, + gc, + src, + xsrc, + ysrc, + xdest, + ydest, + width, + height, + src); +} + static void gdk_drawable_real_draw_pixbuf (GdkDrawable *drawable, GdkGC *gc, @@ -1503,6 +1549,7 @@ gdk_drawable_real_draw_pixbuf (GdkDrawable *drawable, GdkRegion *clip; GdkRegion *drect; GdkRectangle tmp_rect; + GdkDrawable *real_drawable; g_return_if_fail (GDK_IS_PIXBUF (pixbuf)); g_return_if_fail (pixbuf->colorspace == GDK_COLORSPACE_RGB); @@ -1575,7 +1622,19 @@ gdk_drawable_real_draw_pixbuf (GdkDrawable *drawable, /* Actually draw */ if (!gc) gc = _gdk_drawable_get_scratch_gc (drawable, FALSE); - + + /* Drawable is a wrapper here, but at this time we + have already retargeted the destination to any + impl window and set the clip, so what we really + want to do is draw directly on the impl, ignoring + client side subwindows. We also use the impl + in the pixmap target case to avoid resetting the + already set clip on the GC. */ + if (GDK_IS_WINDOW (drawable)) + real_drawable = GDK_WINDOW_OBJECT (drawable)->impl; + else + real_drawable = GDK_PIXMAP_OBJECT (drawable)->impl; + if (pixbuf->has_alpha) { GdkVisual *visual = gdk_drawable_get_visual (drawable); @@ -1645,7 +1704,7 @@ gdk_drawable_real_draw_pixbuf (GdkDrawable *drawable, image->bpl, visual->byte_order, width1, height1); - gdk_draw_image (drawable, gc, image, + gdk_draw_image (real_drawable, gc, image, xs0, ys0, dest_x + x0, dest_y + y0, width1, height1); @@ -1686,7 +1745,7 @@ gdk_drawable_real_draw_pixbuf (GdkDrawable *drawable, { guchar *buf = pixbuf->pixels + src_y * pixbuf->rowstride + src_x * 4; - gdk_draw_rgb_32_image_dithalign (drawable, gc, + gdk_draw_rgb_32_image_dithalign (real_drawable, gc, dest_x, dest_y, width, height, dither, @@ -1697,7 +1756,7 @@ gdk_drawable_real_draw_pixbuf (GdkDrawable *drawable, { guchar *buf = pixbuf->pixels + src_y * pixbuf->rowstride + src_x * 3; - gdk_draw_rgb_image_dithalign (drawable, gc, + gdk_draw_rgb_image_dithalign (real_drawable, gc, dest_x, dest_y, width, height, dither, @@ -1771,5 +1830,81 @@ _gdk_drawable_get_scratch_gc (GdkDrawable *drawable, } } +/** + * _gdk_drawable_get_subwindow_scratch_gc: + * @drawable: A #GdkDrawable + * + * Returns a #GdkGC suitable for drawing on @drawable. The #GdkGC has + * the standard values for @drawable, except for the graphics_exposures + * field which is %TRUE and the subwindow mode which is %GDK_INCLUDE_INFERIORS. + * + * The foreground color of the returned #GdkGC is undefined. The #GdkGC + * must not be altered in any way, except to change its foreground color. + * + * Return value: A #GdkGC suitable for drawing on @drawable + * + * Since: 2.18 + **/ +GdkGC * +_gdk_drawable_get_subwindow_scratch_gc (GdkDrawable *drawable) +{ + GdkScreen *screen; + gint depth; + + g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL); + + screen = gdk_drawable_get_screen (drawable); + + g_return_val_if_fail (!screen->closed, NULL); + + depth = gdk_drawable_get_depth (drawable) - 1; + + if (!screen->subwindow_gcs[depth]) + { + GdkGCValues values; + GdkGCValuesMask mask; + + values.graphics_exposures = TRUE; + values.subwindow_mode = GDK_INCLUDE_INFERIORS; + mask = GDK_GC_EXPOSURES | GDK_GC_SUBWINDOW; + + screen->subwindow_gcs[depth] = + gdk_gc_new_with_values (drawable, &values, mask); + } + + return screen->subwindow_gcs[depth]; +} + + +/* + * _gdk_drawable_get_source_drawable: + * @drawable: a #GdkDrawable + * + * Returns a drawable for the passed @drawable that is guaranteed to be + * usable to create a pixmap (e.g.: not an offscreen window). + * + * Since: 2.16 + */ +GdkDrawable * +_gdk_drawable_get_source_drawable (GdkDrawable *drawable) +{ + g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL); + + if (GDK_DRAWABLE_GET_CLASS (drawable)->get_source_drawable) + return GDK_DRAWABLE_GET_CLASS (drawable)->get_source_drawable (drawable); + + return drawable; +} + +cairo_surface_t * +_gdk_drawable_create_cairo_surface (GdkDrawable *drawable, + int width, + int height) +{ + return GDK_DRAWABLE_GET_CLASS (drawable)->create_cairo_surface (drawable, + width, height); +} + + #define __GDK_DRAW_C__ #include "gdkaliasdef.c" diff --git a/gdk/gdkdrawable.h b/gdk/gdkdrawable.h index 508bf86fcf..44beaf7fdd 100644 --- a/gdk/gdkdrawable.h +++ b/gdk/gdkdrawable.h @@ -200,10 +200,27 @@ struct _GdkDrawableClass cairo_surface_t *(*ref_cairo_surface) (GdkDrawable *drawable); + GdkDrawable *(*get_source_drawable) (GdkDrawable *drawable); + + void (*set_cairo_clip) (GdkDrawable *drawable, + cairo_t *cr); + + cairo_surface_t * (*create_cairo_surface) (GdkDrawable *drawable, + int width, + int height); + + void (*draw_drawable_with_src) (GdkDrawable *drawable, + GdkGC *gc, + GdkDrawable *src, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height, + GdkDrawable *original_src); + /* Padding for future expansion */ - void (*_gdk_reserved4) (void); - void (*_gdk_reserved5) (void); - void (*_gdk_reserved6) (void); void (*_gdk_reserved7) (void); void (*_gdk_reserved9) (void); void (*_gdk_reserved10) (void); @@ -212,7 +229,6 @@ struct _GdkDrawableClass void (*_gdk_reserved13) (void); void (*_gdk_reserved14) (void); void (*_gdk_reserved15) (void); - void (*_gdk_reserved16) (void); }; struct _GdkTrapezoid diff --git a/gdk/gdkevents.c b/gdk/gdkevents.c index 24a29a1fd9..90e16d7bd8 100644 --- a/gdk/gdkevents.c +++ b/gdk/gdkevents.c @@ -120,6 +120,63 @@ _gdk_event_queue_append (GdkDisplay *display, return display->queued_tail; } +/** + * _gdk_event_queue_insert_after: + * @display: a #GdkDisplay + * @sibling: Append after this event. + * @event: Event to append. + * + * Appends an event after the specified event, or if it isn't in + * the queue, onto the tail of the event queue. + * + * Returns: the newly appended list node. + * + * Since: 2.16 + */ +GList* +_gdk_event_queue_insert_after (GdkDisplay *display, + GdkEvent *sibling, + GdkEvent *event) +{ + GList *prev = g_list_find (display->queued_events, sibling); + if (prev && prev->next) + { + display->queued_events = g_list_insert_before (display->queued_events, prev->next, event); + return prev->next; + } + else + return _gdk_event_queue_append (display, event); +} + +/** + * _gdk_event_queue_insert_after: + * @display: a #GdkDisplay + * @sibling: Append after this event. + * @event: Event to append. + * + * Appends an event before the specified event, or if it isn't in + * the queue, onto the tail of the event queue. + * + * Returns: the newly appended list node. + * + * Since: 2.16 + */ +GList* +_gdk_event_queue_insert_before (GdkDisplay *display, + GdkEvent *sibling, + GdkEvent *event) +{ + GList *next = g_list_find (display->queued_events, sibling); + if (next) + { + display->queued_events = g_list_insert_before (display->queued_events, next, event); + return next->prev; + } + else + return _gdk_event_queue_append (display, event); +} + + /** * _gdk_event_queue_remove_link: * @display: a #GdkDisplay @@ -575,6 +632,7 @@ gdk_event_get_time (const GdkEvent *event) case GDK_SETTING: case GDK_OWNER_CHANGE: case GDK_GRAB_BROKEN: + case GDK_EVENT_LAST: /* return current time */ break; } @@ -653,6 +711,7 @@ gdk_event_get_state (const GdkEvent *event, case GDK_SETTING: case GDK_OWNER_CHANGE: case GDK_GRAB_BROKEN: + case GDK_EVENT_LAST: /* no state field */ break; } @@ -884,9 +943,17 @@ gdk_event_get_axis (const GdkEvent *event, void gdk_event_request_motions (const GdkEventMotion *event) { + GdkDisplay *display; + g_return_if_fail (event != NULL); + if (event->type == GDK_MOTION_NOTIFY && event->is_hint) - gdk_device_get_state (event->device, event->window, NULL, NULL); + { + gdk_device_get_state (event->device, event->window, NULL, NULL); + + display = gdk_drawable_get_display (event->window); + _gdk_display_enable_motion_hints (display); + } } /** @@ -1101,13 +1168,16 @@ gdk_synthesize_click (GdkDisplay *display, gint nclicks) { GdkEvent temp_event; + GdkEvent *event_copy; + GList *link; g_return_if_fail (event != NULL); temp_event = *event; temp_event.type = (nclicks == 2) ? GDK_2BUTTON_PRESS : GDK_3BUTTON_PRESS; - - gdk_display_put_event (display, &temp_event); + + event_copy = gdk_event_copy (&temp_event); + link = _gdk_event_queue_append (display, event_copy); } void @@ -1196,6 +1266,9 @@ gdk_synthesize_window_state (GdkWindow *window, ((GdkWindowObject*) window)->state = temp_event.window_state.new_window_state; + if (temp_event.window_state.changed_mask & GDK_WINDOW_STATE_WITHDRAWN) + _gdk_window_update_viewable (window); + /* We only really send the event to toplevels, since * all the window states don't apply to non-toplevels. * Non-toplevels do use the GDK_WINDOW_STATE_WITHDRAWN flag diff --git a/gdk/gdkevents.h b/gdk/gdkevents.h index e64acb7b9f..e6c516c780 100644 --- a/gdk/gdkevents.h +++ b/gdk/gdkevents.h @@ -151,7 +151,8 @@ typedef enum GDK_SETTING = 33, GDK_OWNER_CHANGE = 34, GDK_GRAB_BROKEN = 35, - GDK_DAMAGE = 36 + GDK_DAMAGE = 36, + GDK_EVENT_LAST /* helper variable for decls */ } GdkEventType; /* Event masks. (Used to select what types of events a window @@ -518,7 +519,9 @@ gboolean gdk_events_pending (void); GdkEvent* gdk_event_get (void); GdkEvent* gdk_event_peek (void); +#ifndef GDK_DISABLE_DEPRECATED GdkEvent* gdk_event_get_graphics_expose (GdkWindow *window); +#endif void gdk_event_put (const GdkEvent *event); GdkEvent* gdk_event_new (GdkEventType type); diff --git a/gdk/gdkgc.c b/gdk/gdkgc.c index f3389c70ea..44c2aa7aae 100644 --- a/gdk/gdkgc.c +++ b/gdk/gdkgc.c @@ -43,12 +43,24 @@ struct _GdkGCPrivate { GdkRegion *clip_region; - GdkFill fill; + guint32 region_tag_applied; + int region_tag_offset_x; + int region_tag_offset_y; + + GdkRegion *old_clip_region; + GdkPixmap *old_clip_mask; + GdkBitmap *stipple; GdkPixmap *tile; - + + GdkPixmap *clip_mask; + guint32 fg_pixel; guint32 bg_pixel; + + guint subwindow_mode : 1; + guint fill : 2; + guint exposures : 2; }; #define GDK_GC_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDK_TYPE_GC, GdkGCPrivate)) @@ -150,6 +162,8 @@ _gdk_gc_init (GdkGC *gc, gc->clip_x_origin = values->clip_x_origin; if (values_mask & GDK_GC_CLIP_Y_ORIGIN) gc->clip_y_origin = values->clip_y_origin; + if ((values_mask & GDK_GC_CLIP_MASK) && values->clip_mask) + priv->clip_mask = g_object_ref (values->clip_mask); if (values_mask & GDK_GC_TS_X_ORIGIN) gc->ts_x_origin = values->ts_x_origin; if (values_mask & GDK_GC_TS_Y_ORIGIN) @@ -172,6 +186,12 @@ _gdk_gc_init (GdkGC *gc, priv->fg_pixel = values->foreground.pixel; if (values_mask & GDK_GC_BACKGROUND) priv->bg_pixel = values->background.pixel; + if (values_mask & GDK_GC_SUBWINDOW) + priv->subwindow_mode = values->subwindow_mode; + if (values_mask & GDK_GC_EXPOSURES) + priv->exposures = values->graphics_exposures; + else + priv->exposures = TRUE; gc->colormap = gdk_drawable_get_colormap (drawable); if (gc->colormap) @@ -183,9 +203,15 @@ gdk_gc_finalize (GObject *object) { GdkGC *gc = GDK_GC (object); GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc); - + if (priv->clip_region) gdk_region_destroy (priv->clip_region); + if (priv->old_clip_region) + gdk_region_destroy (priv->old_clip_region); + if (priv->clip_mask) + g_object_unref (priv->clip_mask); + if (priv->old_clip_mask) + g_object_unref (priv->old_clip_mask); if (gc->colormap) g_object_unref (gc->colormap); if (priv->tile) @@ -269,6 +295,12 @@ gdk_gc_set_values (GdkGC *gc, priv = GDK_GC_GET_PRIVATE (gc); + if ((values_mask & GDK_GC_CLIP_X_ORIGIN) || + (values_mask & GDK_GC_CLIP_Y_ORIGIN) || + (values_mask & GDK_GC_CLIP_MASK) || + (values_mask & GDK_GC_SUBWINDOW)) + _gdk_gc_remove_drawable_clip (gc); + if (values_mask & GDK_GC_CLIP_X_ORIGIN) gc->clip_x_origin = values->clip_x_origin; if (values_mask & GDK_GC_CLIP_Y_ORIGIN) @@ -279,6 +311,14 @@ gdk_gc_set_values (GdkGC *gc, gc->ts_y_origin = values->ts_y_origin; if (values_mask & GDK_GC_CLIP_MASK) { + if (priv->clip_mask) + { + g_object_unref (priv->clip_mask); + priv->clip_mask = NULL; + } + if (values->clip_mask) + priv->clip_mask = g_object_ref (values->clip_mask); + if (priv->clip_region) { gdk_region_destroy (priv->clip_region); @@ -313,6 +353,10 @@ gdk_gc_set_values (GdkGC *gc, priv->fg_pixel = values->foreground.pixel; if (values_mask & GDK_GC_BACKGROUND) priv->bg_pixel = values->background.pixel; + if (values_mask & GDK_GC_SUBWINDOW) + priv->subwindow_mode = values->subwindow_mode; + if (values_mask & GDK_GC_EXPOSURES) + priv->exposures = values->graphics_exposures; GDK_GC_GET_CLASS (gc)->set_values (gc, values, values_mask); } @@ -542,18 +586,159 @@ gdk_gc_set_clip_mask (GdkGC *gc, gdk_gc_set_values (gc, &values, GDK_GC_CLIP_MASK); } +/* Takes ownership of passed in region */ static void -_gdk_gc_set_clip_region_internal (GdkGC *gc, - GdkRegion *region) +_gdk_gc_set_clip_region_real (GdkGC *gc, + GdkRegion *region, + gboolean reset_origin) { GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc); + if (priv->clip_mask) + { + g_object_unref (priv->clip_mask); + priv->clip_mask = NULL; + } + if (priv->clip_region) gdk_region_destroy (priv->clip_region); priv->clip_region = region; - _gdk_windowing_gc_set_clip_region (gc, region); + _gdk_windowing_gc_set_clip_region (gc, region, reset_origin); +} + +/* Doesn't copy region, allows not to reset origin */ +void +_gdk_gc_set_clip_region_internal (GdkGC *gc, + GdkRegion *region, + gboolean reset_origin) +{ + _gdk_gc_remove_drawable_clip (gc); + _gdk_gc_set_clip_region_real (gc, region, reset_origin); +} + + +void +_gdk_gc_add_drawable_clip (GdkGC *gc, + guint32 region_tag, + GdkRegion *region, + int offset_x, + int offset_y) +{ + GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc); + + if (priv->region_tag_applied == region_tag && + offset_x == priv->region_tag_offset_x && + offset_y == priv->region_tag_offset_y) + return; /* Already appied this drawable region */ + + if (priv->region_tag_applied) + _gdk_gc_remove_drawable_clip (gc); + + region = gdk_region_copy (region); + if (offset_x != 0 || offset_y != 0) + gdk_region_offset (region, offset_x, offset_y); + + if (priv->clip_mask) + { + int w, h; + GdkPixmap *new_mask; + GdkGC *tmp_gc; + GdkColor black = {0, 0, 0, 0}; + GdkRectangle r; + GdkOverlapType overlap; + + gdk_drawable_get_size (priv->clip_mask, &w, &h); + + r.x = 0; + r.y = 0; + r.width = w; + r.height = h; + + /* Its quite common to expose areas that are completely in or outside + * the region, so we try to avoid allocating bitmaps that are just fully + * set or completely unset. + */ + overlap = gdk_region_rect_in (region, &r); + if (overlap == GDK_OVERLAP_RECTANGLE_PART) + { + /* The region and the mask intersect, create a new clip mask that + includes both areas */ + priv->old_clip_mask = g_object_ref (priv->clip_mask); + new_mask = gdk_pixmap_new (priv->old_clip_mask, w, h, -1); + tmp_gc = _gdk_drawable_get_scratch_gc ((GdkDrawable *)new_mask, FALSE); + + gdk_gc_set_foreground (tmp_gc, &black); + gdk_draw_rectangle (new_mask, tmp_gc, TRUE, 0, 0, -1, -1); + _gdk_gc_set_clip_region_internal (tmp_gc, region, TRUE); /* Takes ownership of region */ + gdk_draw_drawable (new_mask, + tmp_gc, + priv->old_clip_mask, + 0, 0, + 0, 0, + -1, -1); + gdk_gc_set_clip_region (tmp_gc, NULL); + gdk_gc_set_clip_mask (gc, new_mask); + } + else if (overlap == GDK_OVERLAP_RECTANGLE_OUT) + { + /* No intersection, set empty clip region */ + GdkRegion *empty = gdk_region_new (); + + gdk_region_destroy (region); + priv->old_clip_mask = g_object_ref (priv->clip_mask); + priv->clip_region = empty; + _gdk_windowing_gc_set_clip_region (gc, empty, FALSE); + } + else + { + /* Completely inside region, don't set unnecessary clip */ + gdk_region_destroy (region); + return; + } + } + else + { + priv->old_clip_region = priv->clip_region; + priv->clip_region = region; + if (priv->old_clip_region) + gdk_region_intersect (region, priv->old_clip_region); + + _gdk_windowing_gc_set_clip_region (gc, priv->clip_region, FALSE); + } + + priv->region_tag_applied = region_tag; + priv->region_tag_offset_x = offset_x; + priv->region_tag_offset_y = offset_y; +} + +void +_gdk_gc_remove_drawable_clip (GdkGC *gc) +{ + GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc); + + if (priv->region_tag_applied) + { + priv->region_tag_applied = 0; + if (priv->old_clip_mask) + { + gdk_gc_set_clip_mask (gc, priv->old_clip_mask); + g_object_unref (priv->old_clip_mask); + priv->old_clip_mask = NULL; + + if (priv->clip_region) + { + g_object_unref (priv->clip_region); + priv->clip_region = NULL; + } + } + else + { + _gdk_gc_set_clip_region_real (gc, priv->old_clip_region, FALSE); + priv->old_clip_region = NULL; + } + } } /** @@ -573,12 +758,14 @@ gdk_gc_set_clip_rectangle (GdkGC *gc, g_return_if_fail (GDK_IS_GC (gc)); + _gdk_gc_remove_drawable_clip (gc); + if (rectangle) region = gdk_region_rectangle (rectangle); else region = NULL; - _gdk_gc_set_clip_region_internal (gc, region); + _gdk_gc_set_clip_region_real (gc, region, TRUE); } /** @@ -598,12 +785,14 @@ gdk_gc_set_clip_region (GdkGC *gc, g_return_if_fail (GDK_IS_GC (gc)); + _gdk_gc_remove_drawable_clip (gc); + if (region) copy = gdk_region_copy (region); else copy = NULL; - _gdk_gc_set_clip_region_internal (gc, copy); + _gdk_gc_set_clip_region_real (gc, copy, TRUE); } /** @@ -624,6 +813,24 @@ _gdk_gc_get_clip_region (GdkGC *gc) return GDK_GC_GET_PRIVATE (gc)->clip_region; } +/** + * _gdk_gc_get_clip_mask: + * @gc: a #GdkGC + * + * Gets the current clip mask for @gc, if any. + * + * Return value: the clip mask for the GC, or %NULL. + * (if a clip region is set, the return will be %NULL) + * This value is owned by the GC and must not be freed. + **/ +GdkBitmap * +_gdk_gc_get_clip_mask (GdkGC *gc) +{ + g_return_val_if_fail (GDK_IS_GC (gc), NULL); + + return GDK_GC_GET_PRIVATE (gc)->clip_mask; +} + /** * _gdk_gc_get_fill: * @gc: a #GdkGC @@ -640,6 +847,14 @@ _gdk_gc_get_fill (GdkGC *gc) return GDK_GC_GET_PRIVATE (gc)->fill; } +gboolean +_gdk_gc_get_exposures (GdkGC *gc) +{ + g_return_val_if_fail (GDK_IS_GC (gc), FALSE); + + return GDK_GC_GET_PRIVATE (gc)->exposures; +} + /** * _gdk_gc_get_tile: * @gc: a #GdkGC @@ -723,13 +938,27 @@ gdk_gc_set_subwindow (GdkGC *gc, GdkSubwindowMode mode) { GdkGCValues values; + GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc); g_return_if_fail (GDK_IS_GC (gc)); + /* This could get called a lot to reset the subwindow mode in + the client side clipping, so bail out early */ + if (priv->subwindow_mode == mode) + return; + values.subwindow_mode = mode; gdk_gc_set_values (gc, &values, GDK_GC_SUBWINDOW); } +GdkSubwindowMode +_gdk_gc_get_subwindow (GdkGC *gc) +{ + GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc); + + return priv->subwindow_mode; +} + /** * gdk_gc_set_exposures: * @gc: a #GdkGC. @@ -890,6 +1119,26 @@ gdk_gc_copy (GdkGC *dst_gc, dst_priv->clip_region = gdk_region_copy (src_priv->clip_region); else dst_priv->clip_region = NULL; + + dst_priv->region_tag_applied = src_priv->region_tag_applied; + + if (dst_priv->old_clip_region) + gdk_region_destroy (dst_priv->old_clip_region); + + if (src_priv->old_clip_region) + dst_priv->old_clip_region = gdk_region_copy (src_priv->old_clip_region); + else + dst_priv->old_clip_region = NULL; + + if (src_priv->clip_mask) + dst_priv->clip_mask = g_object_ref (src_priv->clip_mask); + else + dst_priv->clip_mask = NULL; + + if (src_priv->old_clip_mask) + dst_priv->old_clip_mask = g_object_ref (src_priv->old_clip_mask); + else + dst_priv->old_clip_mask = NULL; dst_priv->fill = src_priv->fill; @@ -907,6 +1156,8 @@ gdk_gc_copy (GdkGC *dst_gc, dst_priv->fg_pixel = src_priv->fg_pixel; dst_priv->bg_pixel = src_priv->bg_pixel; + dst_priv->subwindow_mode = src_priv->subwindow_mode; + dst_priv->exposures = src_priv->exposures; } /** @@ -1117,6 +1368,8 @@ gc_get_background (GdkGC *gc, * the fill mode will be forced to %GDK_STIPPLED * @gc_changed: pass %FALSE if the @gc has not changed since the * last call to this function + * @target_drawable: The drawable you're drawing in. If passed in + * this is used for client side window clip emulation. * * Set the attributes of a cairo context to match those of a #GdkGC * as far as possible. Some aspects of a #GdkGC, such as clip masks @@ -1127,7 +1380,8 @@ _gdk_gc_update_context (GdkGC *gc, cairo_t *cr, const GdkColor *override_foreground, GdkBitmap *override_stipple, - gboolean gc_changed) + gboolean gc_changed, + GdkDrawable *target_drawable) { GdkGCPrivate *priv; GdkFill fill; @@ -1142,6 +1396,8 @@ _gdk_gc_update_context (GdkGC *gc, priv = GDK_GC_GET_PRIVATE (gc); + _gdk_gc_remove_drawable_clip (gc); + fill = priv->fill; if (override_stipple && fill != GDK_OPAQUE_STIPPLED) fill = GDK_STIPPLED; @@ -1232,6 +1488,10 @@ _gdk_gc_update_context (GdkGC *gc, return; cairo_reset_clip (cr); + /* The reset above resets the window clip rect, so we want to re-set that */ + if (target_drawable && GDK_DRAWABLE_GET_CLASS (target_drawable)->set_cairo_clip) + GDK_DRAWABLE_GET_CLASS (target_drawable)->set_cairo_clip (target_drawable, cr); + if (priv->clip_region) { cairo_save (cr); @@ -1246,6 +1506,7 @@ _gdk_gc_update_context (GdkGC *gc, cairo_clip (cr); } + } diff --git a/gdk/gdkglobals.c b/gdk/gdkglobals.c index 35e9908a29..4c3ad80956 100644 --- a/gdk/gdkglobals.c +++ b/gdk/gdkglobals.c @@ -39,6 +39,7 @@ GList *_gdk_default_filters = NULL; gchar *_gdk_display_name = NULL; gint _gdk_screen_number = -1; gchar *_gdk_display_arg_name = NULL; +gboolean _gdk_native_windows = FALSE; GSList *_gdk_displays = NULL; diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h index 61a5433e2a..0681bdcd18 100644 --- a/gdk/gdkinternals.h +++ b/gdk/gdkinternals.h @@ -107,6 +107,7 @@ extern gint _gdk_error_code; extern gint _gdk_error_warnings; extern guint _gdk_debug_flags; +extern gboolean _gdk_native_windows; #ifdef G_ENABLE_DEBUG @@ -170,6 +171,113 @@ struct _GdkEventPrivate gpointer windowing_data; }; +/* Tracks information about the pointer grab on this display */ +typedef struct +{ + GdkWindow *window; + GdkWindow *native_window; + gulong serial_start; + gulong serial_end; /* exclusive, i.e. not active on serial_end */ + gboolean owner_events; + guint event_mask; + gboolean implicit; + guint32 time; + + gboolean activated; + gboolean implicit_ungrab; +} GdkPointerGrabInfo; + +typedef struct _GdkInputWindow GdkInputWindow; + +/* Private version of GdkWindowObject. The initial part of this strucuture + is public for historical reasons. Don't change that part */ +typedef struct _GdkWindowPaint GdkWindowPaint; + +struct _GdkWindowObject +{ + /* vvvvvvv THIS PART IS PUBLIC. DON'T CHANGE vvvvvvvvvvvvvv */ + GdkDrawable parent_instance; + + GdkDrawable *impl; /* window-system-specific delegate object */ + + GdkWindowObject *parent; + + gpointer user_data; + + gint x; + gint y; + + gint extension_events; + + GList *filters; + GList *children; + + GdkColor bg_color; + GdkPixmap *bg_pixmap; + + GSList *paint_stack; + + GdkRegion *update_area; + guint update_freeze_count; + + guint8 window_type; + guint8 depth; + guint8 resize_count; + + GdkWindowState state; + + guint guffaw_gravity : 1; + guint input_only : 1; + guint modal_hint : 1; + guint composited : 1; + + guint destroyed : 2; + + guint accept_focus : 1; + guint focus_on_map : 1; + guint shaped : 1; + + GdkEventMask event_mask; + + guint update_and_descendants_freeze_count; + + GdkWindowRedirect *redirect; + + /* ^^^^^^^^^^ THIS PART IS PUBLIC. DON'T CHANGE ^^^^^^^^^^ */ + + /* The GdkWindowObject that has the impl, ref:ed if another window. + * This ref is required to keep the wrapper of the impl window alive + * for as long as any GdkWindow references the impl. */ + GdkWindowObject *impl_window; + int abs_x, abs_y; /* Absolute offset in impl */ + gint width, height; + guint32 clip_tag; + GdkRegion *clip_region; /* Clip region (wrt toplevel) in window coords */ + GdkRegion *clip_region_with_children; /* Clip region in window coords */ + GdkCursor *cursor; + gint8 toplevel_window_type; + guint synthesize_crossing_event_queued : 1; + guint effective_visibility : 2; + guint visibility : 2; /* The visibility wrt the toplevel (i.e. based on clip_region) */ + guint native_visibility : 2; /* the native visibility of a impl windows */ + guint viewable : 1; /* mapped and all parents mapped */ + guint applied_shape : 1; + + guint num_offscreen_children; + GdkWindowPaint *implicit_paint; + GdkInputWindow *input_window; /* only set for impl windows */ + + GList *outstanding_moves; + + GdkRegion *shape; + GdkRegion *input_shape; + + cairo_surface_t *cairo_surface; +}; + +#define GDK_WINDOW_TYPE(d) (((GdkWindowObject*)(GDK_WINDOW (d)))->window_type) +#define GDK_WINDOW_DESTROYED(d) (((GdkWindowObject*)(GDK_WINDOW (d)))->destroyed) + extern GdkEventFunc _gdk_event_func; /* Callback for events */ extern gpointer _gdk_event_data; extern GDestroyNotify _gdk_event_notify; @@ -182,15 +290,21 @@ extern gchar *_gdk_display_arg_name; void _gdk_events_queue (GdkDisplay *display); GdkEvent* _gdk_event_unqueue (GdkDisplay *display); -GList* _gdk_event_queue_find_first (GdkDisplay *display); -void _gdk_event_queue_remove_link (GdkDisplay *display, - GList *node); -GList* _gdk_event_queue_prepend (GdkDisplay *display, - GdkEvent *event); -GList* _gdk_event_queue_append (GdkDisplay *display, - GdkEvent *event); -void _gdk_event_button_generate (GdkDisplay *display, - GdkEvent *event); +GList* _gdk_event_queue_find_first (GdkDisplay *display); +void _gdk_event_queue_remove_link (GdkDisplay *display, + GList *node); +GList* _gdk_event_queue_prepend (GdkDisplay *display, + GdkEvent *event); +GList* _gdk_event_queue_append (GdkDisplay *display, + GdkEvent *event); +GList* _gdk_event_queue_insert_after (GdkDisplay *display, + GdkEvent *after_event, + GdkEvent *event); +GList* _gdk_event_queue_insert_before(GdkDisplay *display, + GdkEvent *after_event, + GdkEvent *event); +void _gdk_event_button_generate (GdkDisplay *display, + GdkEvent *event); void _gdk_windowing_event_data_copy (const GdkEvent *src, GdkEvent *dst); @@ -227,28 +341,60 @@ GdkImage *_gdk_drawable_copy_to_image (GdkDrawable *drawable, cairo_surface_t *_gdk_drawable_ref_cairo_surface (GdkDrawable *drawable); +GdkDrawable *_gdk_drawable_get_source_drawable (GdkDrawable *drawable); +cairo_surface_t * _gdk_drawable_create_cairo_surface (GdkDrawable *drawable, + int width, + int height); + /* GC caching */ GdkGC *_gdk_drawable_get_scratch_gc (GdkDrawable *drawable, gboolean graphics_exposures); +GdkGC *_gdk_drawable_get_subwindow_scratch_gc (GdkDrawable *drawable); void _gdk_gc_update_context (GdkGC *gc, cairo_t *cr, const GdkColor *override_foreground, GdkBitmap *override_stipple, - gboolean gc_changed); + gboolean gc_changed, + GdkDrawable *target_drawable); /************************************* * Interfaces used by windowing code * *************************************/ -GdkWindow *_gdk_window_new (GdkWindow *window, - GdkWindowAttr *attributes, - gint attributes_mask); -void _gdk_window_destroy (GdkWindow *window, - gboolean foreign_destroy); -void _gdk_window_clear_update_area (GdkWindow *window); +GdkPixmap *_gdk_pixmap_new (GdkDrawable *drawable, + gint width, + gint height, + gint depth); +GdkPixmap *_gdk_pixmap_create_from_data (GdkDrawable *drawable, + const gchar *data, + gint width, + gint height, + gint depth, + const GdkColor *fg, + const GdkColor *bg); +GdkPixmap *_gdk_bitmap_create_from_data (GdkDrawable *drawable, + const gchar *data, + gint width, + gint height); -void _gdk_screen_close (GdkScreen *screen); +void _gdk_window_impl_new (GdkWindow *window, + GdkWindow *real_parent, + GdkScreen *screen, + GdkVisual *visual, + GdkEventMask event_mask, + GdkWindowAttr *attributes, + gint attributes_mask); +void _gdk_window_destroy (GdkWindow *window, + gboolean foreign_destroy); +void _gdk_window_clear_update_area (GdkWindow *window); +void _gdk_window_update_size (GdkWindow *window); +gboolean _gdk_window_update_viewable (GdkWindow *window); + +void _gdk_window_process_updates_recurse (GdkWindow *window, + GdkRegion *expose_region); + +void _gdk_screen_close (GdkScreen *screen); const char *_gdk_get_sm_client_id (void); @@ -258,11 +404,23 @@ void _gdk_gc_init (GdkGC *gc, GdkGCValuesMask values_mask); GdkRegion *_gdk_gc_get_clip_region (GdkGC *gc); +GdkBitmap *_gdk_gc_get_clip_mask (GdkGC *gc); +gboolean _gdk_gc_get_exposures (GdkGC *gc); GdkFill _gdk_gc_get_fill (GdkGC *gc); GdkPixmap *_gdk_gc_get_tile (GdkGC *gc); GdkBitmap *_gdk_gc_get_stipple (GdkGC *gc); guint32 _gdk_gc_get_fg_pixel (GdkGC *gc); guint32 _gdk_gc_get_bg_pixel (GdkGC *gc); +void _gdk_gc_add_drawable_clip (GdkGC *gc, + guint32 region_tag, + GdkRegion *region, + int offset_x, + int offset_y); +void _gdk_gc_remove_drawable_clip (GdkGC *gc); +void _gdk_gc_set_clip_region_internal (GdkGC *gc, + GdkRegion *region, + gboolean reset_origin); +GdkSubwindowMode _gdk_gc_get_subwindow (GdkGC *gc); /***************************************** * Interfaces provided by windowing code * @@ -284,60 +442,50 @@ void _gdk_windowing_set_default_display (GdkDisplay *display); gchar *_gdk_windowing_substitute_screen_number (const gchar *display_name, gint screen_number); +gulong _gdk_windowing_window_get_next_serial (GdkDisplay *display); void _gdk_windowing_window_get_offsets (GdkWindow *window, gint *x_offset, gint *y_offset); +GdkRegion *_gdk_windowing_window_get_shape (GdkWindow *window); +GdkRegion *_gdk_windowing_window_get_input_shape(GdkWindow *window); +GdkRegion *_gdk_windowing_get_shape_for_mask (GdkBitmap *mask); +void _gdk_windowing_window_beep (GdkWindow *window); + void _gdk_windowing_get_pointer (GdkDisplay *display, GdkScreen **screen, gint *x, gint *y, GdkModifierType *mask); -GdkWindow* _gdk_windowing_window_get_pointer (GdkDisplay *display, - GdkWindow *window, - gint *x, - gint *y, - GdkModifierType *mask); GdkWindow* _gdk_windowing_window_at_pointer (GdkDisplay *display, gint *win_x, - gint *win_y); + gint *win_y, + GdkModifierType *mask, + gboolean get_toplevel); +GdkGrabStatus _gdk_windowing_pointer_grab (GdkWindow *window, + GdkWindow *native, + gboolean owner_events, + GdkEventMask event_mask, + GdkWindow *confine_to, + GdkCursor *cursor, + guint32 time); +void _gdk_windowing_got_event (GdkDisplay *display, + GList *event_link, + GdkEvent *event, + gulong serial); + +void _gdk_windowing_window_process_updates_recurse (GdkWindow *window, + GdkRegion *expose_region); +void _gdk_windowing_before_process_all_updates (void); +void _gdk_windowing_after_process_all_updates (void); /* Return the number of bits-per-pixel for images of the specified depth. */ gint _gdk_windowing_get_bits_for_depth (GdkDisplay *display, gint depth); -void _gdk_window_reparent (GdkWindow *window, - GdkWindow *new_parent, - gint x, - gint y); #define GDK_WINDOW_IS_MAPPED(window) ((((GdkWindowObject*)window)->state & GDK_WINDOW_STATE_WITHDRAWN) == 0) -/* Called before processing updates for a window. This gives the windowing - * layer a chance to save the region for later use in avoiding duplicate - * exposes. The return value indicates whether the function has a saved - * the region; if the result is TRUE, then the windowing layer is responsible - * for destroying the region later. - */ -gboolean _gdk_windowing_window_queue_antiexpose (GdkWindow *window, - GdkRegion *area); - -/* Called to do the windowing system specific part of gdk_window_destroy(), - * - * window: The window being destroyed - * recursing: If TRUE, then this is being called because a parent - * was destroyed. This generally means that the call to the windowing system - * to destroy the window can be omitted, since it will be destroyed as a result - * of the parent being destroyed. Unless @foreign_destroy - * - * foreign_destroy: If TRUE, the window or a parent was destroyed by some external - * agency. The window has already been destroyed and no windowing - * system calls should be made. (This may never happen for some - * windowing systems.) - */ -void _gdk_windowing_window_destroy (GdkWindow *window, - gboolean recursing, - gboolean foreign_destroy); /* Called when gdk_window_destroy() is called on a foreign window * or an ancestor of the foreign window. It should generally reparent @@ -365,15 +513,9 @@ struct _GdkPaintableIface GTypeInterface g_iface; void (* begin_paint_region) (GdkPaintable *paintable, + GdkWindow *window, const GdkRegion *region); void (* end_paint) (GdkPaintable *paintable); - - void (* invalidate_maybe_recurse) (GdkPaintable *paintable, - const GdkRegion *region, - gboolean (*child_func) (GdkWindow *, gpointer), - gpointer user_data); - void (* process_updates) (GdkPaintable *paintable, - gboolean update_children); }; GType _gdk_paintable_get_type (void) G_GNUC_CONST; @@ -387,6 +529,7 @@ GType _gdk_pixmap_impl_get_type (void) G_GNUC_CONST; * _gdk_windowing_gc_set_clip_region: * @gc: a #GdkGC * @region: the new clip region + * @reset_origin: if TRUE, reset the clip_x/y_origin values to 0 * * Do any window-system specific processing necessary * for a change in clip region. Since the clip origin @@ -398,7 +541,8 @@ GType _gdk_pixmap_impl_get_type (void) G_GNUC_CONST; * will already return the new region. **/ void _gdk_windowing_gc_set_clip_region (GdkGC *gc, - const GdkRegion *region); + const GdkRegion *region, + gboolean reset_origin); /** * _gdk_windowing_gc_copy: @@ -435,6 +579,102 @@ char *_gdk_windowing_get_startup_notify_id (GAppLaunchContext *context, void _gdk_windowing_launch_failed (GAppLaunchContext *context, const char *startup_notify_id); +GdkPointerGrabInfo *_gdk_display_get_active_pointer_grab (GdkDisplay *display); +void _gdk_display_pointer_grab_update (GdkDisplay *display, + gulong current_serial); +GdkPointerGrabInfo *_gdk_display_get_last_pointer_grab (GdkDisplay *display); +GdkPointerGrabInfo *_gdk_display_add_pointer_grab (GdkDisplay *display, + GdkWindow *window, + GdkWindow *native_window, + gboolean owner_events, + GdkEventMask event_mask, + unsigned long serial_start, + guint32 time, + gboolean implicit); +GdkPointerGrabInfo * _gdk_display_has_pointer_grab (GdkDisplay *display, + gulong serial); +gboolean _gdk_display_end_pointer_grab (GdkDisplay *display, + gulong serial, + GdkWindow *if_child, + gboolean implicit); +void _gdk_display_set_has_keyboard_grab (GdkDisplay *display, + GdkWindow *window, + GdkWindow *native_window, + gboolean owner_events, + unsigned long serial, + guint32 time); +void _gdk_display_unset_has_keyboard_grab (GdkDisplay *display, + gboolean implicit); +void _gdk_display_enable_motion_hints (GdkDisplay *display); + + +void _gdk_window_invalidate_for_expose (GdkWindow *window, + GdkRegion *region); + +void _gdk_windowing_set_cairo_surface_size (cairo_surface_t *surface, + int width, + int height); + +cairo_surface_t * _gdk_windowing_create_cairo_surface (GdkDrawable *drawable, + int width, + int height); +GdkWindow * _gdk_window_find_child_at (GdkWindow *window, + int x, int y); +GdkWindow * _gdk_window_find_descendant_at (GdkWindow *toplevel, + double x, double y, + double *found_x, + double *found_y); + +void _gdk_window_add_damage (GdkWindow *toplevel, + GdkRegion *damaged_region); + +GdkEvent * _gdk_make_event (GdkWindow *window, + GdkEventType type, + GdkEvent *event_in_queue, + gboolean before_event); +gboolean _gdk_window_event_parent_of (GdkWindow *parent, + GdkWindow *child); + +void _gdk_synthesize_crossing_events (GdkDisplay *display, + GdkWindow *src, + GdkWindow *dest, + GdkCrossingMode mode, + gint toplevel_x, + gint toplevel_y, + GdkModifierType mask, + guint32 time_, + GdkEvent *event_in_queue, + gulong serial, + gboolean non_linear); +void _gdk_display_set_window_under_pointer (GdkDisplay *display, + GdkWindow *window); + + +void _gdk_synthesize_crossing_events_for_geometry_change (GdkWindow *changed_window); + +GdkRegion *_gdk_window_calculate_full_clip_region (GdkWindow *window, + GdkWindow *base_window, + gboolean do_children, + gint *base_x_offset, + gint *base_y_offset); +gboolean _gdk_window_has_impl (GdkWindow *window); +GdkWindow * _gdk_window_get_impl_window (GdkWindow *window); +GdkWindow *_gdk_window_get_input_window_for_event (GdkWindow *native_window, + GdkEventType event_type, + int x, int y, + gulong serial); +GdkRegion *_gdk_region_new_from_yxbanded_rects (GdkRectangle *rects, int n_rects); + +/***************************** + * offscreen window routines * + *****************************/ +GType gdk_offscreen_window_get_type (void); +void _gdk_offscreen_window_new (GdkWindow *window, + GdkScreen *screen, + GdkVisual *visual, + GdkWindowAttr *attributes, + gint attributes_mask); + /************************************ * Initialization and exit routines * diff --git a/gdk/gdkkeysyms-update.pl b/gdk/gdkkeysyms-update.pl index 4f59fd2b79..bdfb9c29ec 100755 --- a/gdk/gdkkeysyms-update.pl +++ b/gdk/gdkkeysyms-update.pl @@ -1,13 +1,15 @@ #!/usr/bin/env perl -# Updates http://svn.gnome.org/viewcvs/gtk%2B/trunk/gdk/gdkkeysyms.h?view=log from upstream (X.org 7.x), +# Updates http://git.gnome.org/cgit/gtk+/tree/gdk/gdkkeysyms.h from upstream (X.org 7.x), # from http://gitweb.freedesktop.org/?p=xorg/proto/x11proto.git;a=blob_plain;f=keysymdef.h # # Author : Simos Xenitellis . +# Authos : Bastien Nocera # Version : 1.2 # # Input : http://gitweb.freedesktop.org/?p=xorg/proto/x11proto.git;a=blob_plain;f=keysymdef.h -# Output : http://svn.gnome.org/svn/gtk+/trunk/gdk/gdkkeysyms.h +# Input : http://gitweb.freedesktop.org/?p=xorg/proto/x11proto.git;a=blob_plain;f=XF86keysym.h +# Output : http://git.gnome.org/cgit/gtk+/tree/gdk/gdkkeysyms.h # # Notes : It downloads keysymdef.h from the Internet, if not found locally, # Notes : and creates an updated gdkkeysyms.h @@ -33,6 +35,20 @@ else print "as found at http://gitweb.freedesktop.org/?p=xorg/proto/x11proto.git;a=blob;f=keysymdef.h\n\n"; } +if ( ! -f "XF86keysym.h" ) +{ + print "Trying to download XF86keysym.h from\n"; + print "http://gitweb.freedesktop.org/?p=xorg/proto/x11proto.git;a=blob_plain;f=XF86keysym.h\n"; + die "Unable to download keysymdef.h from http://gitweb.freedesktop.org/?p=xorg/proto/x11proto.git;a=blob_plain;f=XF86keysym.h\n" + unless system("wget -c -O XF86keysym.h \"http://gitweb.freedesktop.org/?p=xorg/proto/x11proto.git;a=blob_plain;f=XF86keysym.h\"") == 0; + print " done.\n\n"; +} +else +{ + print "We are using existing XF86keysym.h found in this directory.\n"; + print "It is assumed that you took care and it is a recent version\n"; + print "as found at http://gitweb.freedesktop.org/?p=xorg/proto/x11proto.git;a=blob;f=XF86keysym.h\n\n"; +} if ( -f "gdkkeysyms.h" ) { @@ -41,7 +57,7 @@ if ( -f "gdkkeysyms.h" ) die "Exiting...\n\n"; } -# Source: http://cvs.freedesktop.org/xorg/xc/include/keysymdef.h +# Source: http://gitweb.freedesktop.org/?p=xorg/proto/x11proto.git;a=blob;f=keysymdef.h die "Could not open file keysymdef.h: $!\n" unless open(IN_KEYSYMDEF, "<:utf8", "keysymdef.h"); # Output: gtk+/gdk/gdkkeysyms.h @@ -50,7 +66,7 @@ die "Could not open file gdkkeysyms.h: $!\n" unless open(OUT_GDKKEYSYMS, ">:utf8 print OUT_GDKKEYSYMS<) printf OUT_GDKKEYSYMS "#define %s 0x%03x\n", $keysymelements[1], hex($keysymelements[2]); } +close IN_KEYSYMDEF; + #$gdksyms{"0"} = "0000"; -close IN_KEYSYMDEF; +# Source: http://gitweb.freedesktop.org/?p=xorg/proto/x11proto.git;a=blob;f=XF86keysym.h +die "Could not open file XF86keysym.h: $!\n" unless open(IN_XF86KEYSYM, "<:utf8", "XF86keysym.h"); + +while () +{ + next if ( ! /^#define / ); + + @keysymelements = split(/\s+/); + die "Internal error, no \@keysymelements: $_\n" unless @keysymelements; + + $_ = $keysymelements[1]; + die "Internal error, was expecting \"XF86XK_*\", found: $_\n" if ( ! /^XF86XK_/ ); + + # Work-around https://bugs.freedesktop.org/show_bug.cgi?id=11193 + if ($_ eq "XF86XK_XF86BackForward") { + $keysymelements[1] = "XF86XK_AudioForward"; + } + # XF86XK_Clear could end up a dupe of XK_Clear + # XF86XK_Select could end up a dupe of XK_Select + if ($_ eq "XF86XK_Clear") { + $keysymelements[1] = "XF86XK_WindowClear"; + } + if ($_ eq "XF86XK_Select") { + $keysymelements[1] = "XF86XK_SelectButton"; + } + + # Ignore XF86XK_Q + next if ( $_ eq "XF86XK_Q"); + # XF86XK_Calculater is misspelled, and a dupe + next if ( $_ eq "XF86XK_Calculater"); + + $_ = $keysymelements[2]; + die "Internal error, was expecting \"0x*\", found: $_\n" if ( ! /^0x/ ); + + $keysymelements[1] =~ s/^XF86XK_/GDK_/g; + + printf OUT_GDKKEYSYMS "#define %s 0x%03x\n", $keysymelements[1], hex($keysymelements[2]); +} + +close IN_XF86KEYSYM; print OUT_GDKKEYSYMS< +#include +#include "gdk.h" +#include "gdkwindow.h" +#include "gdkinternals.h" +#include "gdkwindowimpl.h" +#include "gdkpixmap.h" +#include "gdkdrawable.h" +#include "gdktypes.h" +#include "gdkscreen.h" +#include "gdkgc.h" +#include "gdkcolor.h" +#include "gdkcursor.h" +#include "gdkalias.h" + +/* LIMITATIONS: + * + * Offscreen windows can't be the child of a foreign window, + * nor contain foreign windows + * GDK_POINTER_MOTION_HINT_MASK isn't effective + */ + +typedef struct _GdkOffscreenWindow GdkOffscreenWindow; +typedef struct _GdkOffscreenWindowClass GdkOffscreenWindowClass; + +struct _GdkOffscreenWindow +{ + GdkDrawable parent_instance; + + GdkWindow *wrapper; + GdkCursor *cursor; + GdkColormap *colormap; + GdkScreen *screen; + + GdkPixmap *pixmap; + GdkWindow *embedder; +}; + +struct _GdkOffscreenWindowClass +{ + GdkDrawableClass parent_class; +}; + +#define GDK_TYPE_OFFSCREEN_WINDOW (gdk_offscreen_window_get_type()) +#define GDK_OFFSCREEN_WINDOW(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_OFFSCREEN_WINDOW, GdkOffscreenWindow)) +#define GDK_IS_OFFSCREEN_WINDOW(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_OFFSCREEN_WINDOW)) +#define GDK_OFFSCREEN_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_OFFSCREEN_WINDOW, GdkOffscreenWindowClass)) +#define GDK_IS_OFFSCREEN_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_OFFSCREEN_WINDOW)) +#define GDK_OFFSCREEN_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_OFFSCREEN_WINDOW, GdkOffscreenWindowClass)) + +static void gdk_offscreen_window_impl_iface_init (GdkWindowImplIface *iface); +static void gdk_offscreen_window_hide (GdkWindow *window); + +G_DEFINE_TYPE_WITH_CODE (GdkOffscreenWindow, + gdk_offscreen_window, + GDK_TYPE_DRAWABLE, + G_IMPLEMENT_INTERFACE (GDK_TYPE_WINDOW_IMPL, + gdk_offscreen_window_impl_iface_init)); + + +static void +gdk_offscreen_window_finalize (GObject *object) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (object); + + if (offscreen->cursor) + gdk_cursor_unref (offscreen->cursor); + + offscreen->cursor = NULL; + + g_object_unref (offscreen->pixmap); + + G_OBJECT_CLASS (gdk_offscreen_window_parent_class)->finalize (object); +} + +static void +gdk_offscreen_window_init (GdkOffscreenWindow *window) +{ +} + +static void +gdk_offscreen_window_destroy (GdkWindow *window, + gboolean recursing, + gboolean foreign_destroy) +{ + GdkWindowObject *private = GDK_WINDOW_OBJECT (window); + GdkOffscreenWindow *offscreen; + + offscreen = GDK_OFFSCREEN_WINDOW (private->impl); + + gdk_offscreen_window_set_embedder (window, NULL); + + if (!recursing) + gdk_offscreen_window_hide (window); + + g_object_unref (offscreen->colormap); + offscreen->colormap = NULL; +} + +static gboolean +is_parent_of (GdkWindow *parent, + GdkWindow *child) +{ + GdkWindow *w; + + w = child; + while (w != NULL) + { + if (w == parent) + return TRUE; + + w = gdk_window_get_parent (w); + } + + return FALSE; +} + +static GdkGC * +gdk_offscreen_window_create_gc (GdkDrawable *drawable, + GdkGCValues *values, + GdkGCValuesMask values_mask) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + + return gdk_gc_new_with_values (offscreen->pixmap, values, values_mask); +} + +static GdkImage* +gdk_offscreen_window_copy_to_image (GdkDrawable *drawable, + GdkImage *image, + gint src_x, + gint src_y, + gint dest_x, + gint dest_y, + gint width, + gint height) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + + return gdk_drawable_copy_to_image (offscreen->pixmap, + image, + src_x, + src_y, + dest_x, dest_y, + width, height); +} + +static cairo_surface_t * +gdk_offscreen_window_ref_cairo_surface (GdkDrawable *drawable) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + + return _gdk_drawable_ref_cairo_surface (offscreen->pixmap); +} + +static GdkColormap* +gdk_offscreen_window_get_colormap (GdkDrawable *drawable) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + + return offscreen->colormap; +} + +static void +gdk_offscreen_window_set_colormap (GdkDrawable *drawable, + GdkColormap*colormap) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + + if (colormap && GDK_WINDOW_DESTROYED (offscreen->wrapper)) + return; + + if (offscreen->colormap == colormap) + return; + + if (offscreen->colormap) + g_object_unref (offscreen->colormap); + + offscreen->colormap = colormap; + if (offscreen->colormap) + g_object_ref (offscreen->colormap); +} + + +static gint +gdk_offscreen_window_get_depth (GdkDrawable *drawable) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + + return gdk_drawable_get_depth (offscreen->wrapper); +} + +static GdkDrawable * +gdk_offscreen_window_get_source_drawable (GdkDrawable *drawable) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + + return _gdk_drawable_get_source_drawable (offscreen->pixmap); +} + +static GdkDrawable * +gdk_offscreen_window_get_composite_drawable (GdkDrawable *drawable, + gint x, + gint y, + gint width, + gint height, + gint *composite_x_offset, + gint *composite_y_offset) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + + return g_object_ref (offscreen->pixmap); +} + +static GdkScreen* +gdk_offscreen_window_get_screen (GdkDrawable *drawable) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + + return offscreen->screen; +} + +static GdkVisual* +gdk_offscreen_window_get_visual (GdkDrawable *drawable) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + + return gdk_drawable_get_visual (offscreen->wrapper); +} + +static void +add_damage (GdkOffscreenWindow *offscreen, + int x, int y, + int w, int h) +{ + GdkRectangle rect; + GdkRegion *damage; + + rect.x = x; + rect.y = y; + rect.width = w; + rect.height = h; + + damage = gdk_region_rectangle (&rect); + _gdk_window_add_damage (offscreen->wrapper, damage); + gdk_region_destroy (damage); +} + +static GdkDrawable * +get_real_drawable (GdkOffscreenWindow *offscreen) +{ + GdkPixmapObject *pixmap; + pixmap = (GdkPixmapObject *) offscreen->pixmap; + return GDK_DRAWABLE (pixmap->impl); +} + +static void +gdk_offscreen_window_draw_drawable (GdkDrawable *drawable, + GdkGC *gc, + GdkPixmap *src, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height, + GdkDrawable *original_src) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + GdkDrawable *real_drawable = get_real_drawable (offscreen); + + gdk_draw_drawable (real_drawable, gc, + src, xsrc, ysrc, + xdest, ydest, + width, height); + + add_damage (offscreen, xdest, ydest, width, height); +} + +static void +gdk_offscreen_window_draw_rectangle (GdkDrawable *drawable, + GdkGC *gc, + gboolean filled, + gint x, + gint y, + gint width, + gint height) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + GdkDrawable *real_drawable = get_real_drawable (offscreen); + + gdk_draw_rectangle (real_drawable, + gc, filled, x, y, width, height); + + add_damage (offscreen, x, y, width, height); + +} + +static void +gdk_offscreen_window_draw_arc (GdkDrawable *drawable, + GdkGC *gc, + gboolean filled, + gint x, + gint y, + gint width, + gint height, + gint angle1, + gint angle2) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + GdkDrawable *real_drawable = get_real_drawable (offscreen); + + gdk_draw_arc (real_drawable, + gc, + filled, + x, + y, + width, + height, + angle1, + angle2); + add_damage (offscreen, x, y, width, height); +} + +static void +gdk_offscreen_window_draw_polygon (GdkDrawable *drawable, + GdkGC *gc, + gboolean filled, + GdkPoint *points, + gint npoints) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + GdkDrawable *real_drawable = get_real_drawable (offscreen); + + gdk_draw_polygon (real_drawable, + gc, + filled, + points, + npoints); + + if (npoints > 0) + { + int min_x, min_y, max_x, max_y, i; + + min_x = max_x = points[0].x; + min_y = max_y = points[0].y; + + for (i = 1; i < npoints; i++) + { + min_x = MIN (min_x, points[i].x); + max_x = MAX (max_x, points[i].x); + min_y = MIN (min_y, points[i].y); + max_y = MAX (max_y, points[i].y); + } + + add_damage (offscreen, min_x, min_y, + max_x - min_x, + max_y - min_y); + } +} + +static void +gdk_offscreen_window_draw_text (GdkDrawable *drawable, + GdkFont *font, + GdkGC *gc, + gint x, + gint y, + const gchar *text, + gint text_length) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + GdkDrawable *real_drawable = get_real_drawable (offscreen); + GdkWindowObject *private = GDK_WINDOW_OBJECT (offscreen->wrapper); + + gdk_draw_text (real_drawable, + font, + gc, + x, + y, + text, + text_length); + + /* Hard to compute the minimal size, not that often used anyway. */ + add_damage (offscreen, 0, 0, private->width, private->height); +} + +static void +gdk_offscreen_window_draw_text_wc (GdkDrawable *drawable, + GdkFont *font, + GdkGC *gc, + gint x, + gint y, + const GdkWChar *text, + gint text_length) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + GdkDrawable *real_drawable = get_real_drawable (offscreen); + GdkWindowObject *private = GDK_WINDOW_OBJECT (offscreen->wrapper); + + gdk_draw_text_wc (real_drawable, + font, + gc, + x, + y, + text, + text_length); + + /* Hard to compute the minimal size, not that often used anyway. */ + add_damage (offscreen, 0, 0, private->width, private->height); +} + +static void +gdk_offscreen_window_draw_points (GdkDrawable *drawable, + GdkGC *gc, + GdkPoint *points, + gint npoints) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + GdkDrawable *real_drawable = get_real_drawable (offscreen); + + gdk_draw_points (real_drawable, + gc, + points, + npoints); + + + if (npoints > 0) + { + int min_x, min_y, max_x, max_y, i; + + min_x = max_x = points[0].x; + min_y = max_y = points[0].y; + + for (i = 1; i < npoints; i++) + { + min_x = MIN (min_x, points[i].x); + max_x = MAX (max_x, points[i].x); + min_y = MIN (min_y, points[i].y); + max_y = MAX (max_y, points[i].y); + } + + add_damage (offscreen, min_x, min_y, + max_x - min_x, + max_y - min_y); + } +} + +static void +gdk_offscreen_window_draw_segments (GdkDrawable *drawable, + GdkGC *gc, + GdkSegment *segs, + gint nsegs) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + GdkDrawable *real_drawable = get_real_drawable (offscreen); + + gdk_draw_segments (real_drawable, + gc, + segs, + nsegs); + + if (nsegs > 0) + { + int min_x, min_y, max_x, max_y, i; + + min_x = max_x = segs[0].x1; + min_y = max_y = segs[0].y1; + + for (i = 1; i < nsegs; i++) + { + min_x = MIN (min_x, segs[i].x1); + max_x = MAX (max_x, segs[i].x1); + min_x = MIN (min_x, segs[i].x2); + max_x = MAX (max_x, segs[i].x2); + min_y = MIN (min_y, segs[i].y1); + max_y = MAX (max_y, segs[i].y1); + min_y = MIN (min_y, segs[i].y2); + max_y = MAX (max_y, segs[i].y2); + } + + add_damage (offscreen, min_x, min_y, + max_x - min_x, + max_y - min_y); + } + +} + +static void +gdk_offscreen_window_draw_lines (GdkDrawable *drawable, + GdkGC *gc, + GdkPoint *points, + gint npoints) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + GdkDrawable *real_drawable = get_real_drawable (offscreen); + GdkWindowObject *private = GDK_WINDOW_OBJECT (offscreen->wrapper); + + gdk_draw_lines (real_drawable, + gc, + points, + npoints); + + /* Hard to compute the minimal size, as we don't know the line + width, and since joins are hard to calculate. + Its not that often used anyway, damage it all */ + add_damage (offscreen, 0, 0, private->width, private->height); +} + +static void +gdk_offscreen_window_draw_image (GdkDrawable *drawable, + GdkGC *gc, + GdkImage *image, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + GdkDrawable *real_drawable = get_real_drawable (offscreen); + + gdk_draw_image (real_drawable, + gc, + image, + xsrc, + ysrc, + xdest, + ydest, + width, + height); + + add_damage (offscreen, xdest, ydest, width, height); +} + + +static void +gdk_offscreen_window_draw_pixbuf (GdkDrawable *drawable, + GdkGC *gc, + GdkPixbuf *pixbuf, + gint src_x, + gint src_y, + gint dest_x, + gint dest_y, + gint width, + gint height, + GdkRgbDither dither, + gint x_dither, + gint y_dither) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + GdkDrawable *real_drawable = get_real_drawable (offscreen); + + gdk_draw_pixbuf (real_drawable, + gc, + pixbuf, + src_x, + src_y, + dest_x, + dest_y, + width, + height, + dither, + x_dither, + y_dither); + + add_damage (offscreen, dest_x, dest_y, width, height); + +} + +void +_gdk_offscreen_window_new (GdkWindow *window, + GdkScreen *screen, + GdkVisual *visual, + GdkWindowAttr *attributes, + gint attributes_mask) +{ + GdkWindowObject *private; + GdkOffscreenWindow *offscreen; + + g_return_if_fail (attributes != NULL); + + if (attributes->wclass != GDK_INPUT_OUTPUT) + return; /* Can't support input only offscreens */ + + private = (GdkWindowObject *)window; + + if (private->parent != NULL && GDK_WINDOW_DESTROYED (private->parent)) + return; + + private->impl = g_object_new (GDK_TYPE_OFFSCREEN_WINDOW, NULL); + offscreen = GDK_OFFSCREEN_WINDOW (private->impl); + offscreen->wrapper = window; + + offscreen->screen = screen; + + if (attributes_mask & GDK_WA_COLORMAP) + offscreen->colormap = g_object_ref (attributes->colormap); + else + { + if (gdk_screen_get_system_visual (screen) == visual) + { + offscreen->colormap = gdk_screen_get_system_colormap (screen); + g_object_ref (offscreen->colormap); + } + else + offscreen->colormap = gdk_colormap_new (visual, FALSE); + } + + offscreen->pixmap = gdk_pixmap_new ((GdkDrawable *)private->parent, + private->width, + private->height, + private->depth); +} + +static gboolean +gdk_offscreen_window_reparent (GdkWindow *window, + GdkWindow *new_parent, + gint x, + gint y) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowObject *new_parent_private = (GdkWindowObject *)new_parent; + GdkWindowObject *old_parent; + gboolean was_mapped; + + if (new_parent) + { + /* No input-output children of input-only windows */ + if (new_parent_private->input_only && !private->input_only) + return FALSE; + + /* Don't create loops in hierarchy */ + if (is_parent_of (window, new_parent)) + return FALSE; + } + + was_mapped = GDK_WINDOW_IS_MAPPED (window); + + gdk_window_hide (window); + + if (private->parent) + private->parent->children = g_list_remove (private->parent->children, window); + + old_parent = private->parent; + private->parent = new_parent_private; + private->x = x; + private->y = y; + + if (new_parent_private) + private->parent->children = g_list_prepend (private->parent->children, window); + + _gdk_synthesize_crossing_events_for_geometry_change (window); + if (old_parent) + _gdk_synthesize_crossing_events_for_geometry_change (GDK_WINDOW (old_parent)); + + return was_mapped; +} + +static void +from_embedder (GdkWindow *window, + double embedder_x, double embedder_y, + double *offscreen_x, double *offscreen_y) +{ + GdkWindowObject *private; + + private = (GdkWindowObject *)window; + + g_signal_emit_by_name (private->impl_window, + "from-embedder", + embedder_x, embedder_y, + offscreen_x, offscreen_y, + NULL); +} + +static void +to_embedder (GdkWindow *window, + double offscreen_x, double offscreen_y, + double *embedder_x, double *embedder_y) +{ + GdkWindowObject *private; + + private = (GdkWindowObject *)window; + + g_signal_emit_by_name (private->impl_window, + "to-embedder", + offscreen_x, offscreen_y, + embedder_x, embedder_y, + NULL); +} + +static gint +gdk_offscreen_window_get_root_coords (GdkWindow *window, + gint x, + gint y, + gint *root_x, + gint *root_y) +{ + GdkWindowObject *private = GDK_WINDOW_OBJECT (window); + GdkOffscreenWindow *offscreen; + int tmpx, tmpy; + + tmpx = x; + tmpy = y; + + offscreen = GDK_OFFSCREEN_WINDOW (private->impl); + if (offscreen->embedder) + { + double dx, dy; + to_embedder (window, + x, y, + &dx, &dy); + tmpx = floor (dx + 0.5); + tmpy = floor (dy + 0.5); + gdk_window_get_root_coords (offscreen->embedder, + tmpx, tmpy, + &tmpx, &tmpy); + + } + + if (root_x) + *root_x = tmpx; + if (root_y) + *root_y = tmpy; + + return TRUE; +} + +static gint +gdk_offscreen_window_get_deskrelative_origin (GdkWindow *window, + gint *x, + gint *y) +{ + GdkWindowObject *private = GDK_WINDOW_OBJECT (window); + GdkOffscreenWindow *offscreen; + int tmpx, tmpy; + + tmpx = 0; + tmpy = 0; + + offscreen = GDK_OFFSCREEN_WINDOW (private->impl); + if (offscreen->embedder) + { + double dx, dy; + gdk_window_get_deskrelative_origin (offscreen->embedder, + &tmpx, &tmpy); + + to_embedder (window, + 0, 0, + &dx, &dy); + tmpx = floor (tmpx + dx + 0.5); + tmpy = floor (tmpy + dy + 0.5); + } + + + if (x) + *x = tmpx; + if (y) + *y = tmpy; + + return TRUE; +} + +static gboolean +gdk_offscreen_window_get_pointer (GdkWindow *window, + gint *x, + gint *y, + GdkModifierType *mask) +{ + GdkWindowObject *private = GDK_WINDOW_OBJECT (window); + GdkOffscreenWindow *offscreen; + int tmpx, tmpy; + double dtmpx, dtmpy; + GdkModifierType tmpmask; + + tmpx = 0; + tmpy = 0; + tmpmask = 0; + + offscreen = GDK_OFFSCREEN_WINDOW (private->impl); + if (offscreen->embedder != NULL) + { + gdk_window_get_pointer (offscreen->embedder, &tmpx, &tmpy, &tmpmask); + from_embedder (window, + tmpx, tmpy, + &dtmpx, &dtmpy); + tmpx = floor (dtmpx + 0.5); + tmpy = floor (dtmpy + 0.5); + } + + if (x) + *x = tmpx; + if (y) + *y = tmpy; + if (mask) + *mask = tmpmask; + return TRUE; +} + +/** + * gdk_offscreen_window_get_pixmap: + * @window: a #GdkWindow + * + * Gets the offscreen pixmap that an offscreen window renders into. + * If you need to keep this around over window resizes, you need to + * add a reference to it. + * + * Returns: The offscreen pixmap, or %NULL if not offscreen + * + * Since: 2.18 + */ +GdkPixmap * +gdk_offscreen_window_get_pixmap (GdkWindow *window) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkOffscreenWindow *offscreen; + + g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE); + + if (!GDK_IS_OFFSCREEN_WINDOW (private->impl)) + return NULL; + + offscreen = GDK_OFFSCREEN_WINDOW (private->impl); + return offscreen->pixmap; +} + +static void +gdk_offscreen_window_raise (GdkWindow *window) +{ + /* gdk_window_raise already changed the stacking order */ + _gdk_synthesize_crossing_events_for_geometry_change (window); +} + +static void +gdk_offscreen_window_lower (GdkWindow *window) +{ + /* gdk_window_lower already changed the stacking order */ + _gdk_synthesize_crossing_events_for_geometry_change (window); +} + +static void +gdk_offscreen_window_move_resize_internal (GdkWindow *window, + gint x, + gint y, + gint width, + gint height, + gboolean send_expose_events) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkOffscreenWindow *offscreen; + gint dx, dy, dw, dh; + GdkGC *gc; + GdkPixmap *old_pixmap; + + offscreen = GDK_OFFSCREEN_WINDOW (private->impl); + + if (width < 1) + width = 1; + if (height < 1) + height = 1; + + if (private->destroyed) + return; + + dx = x - private->x; + dy = y - private->y; + dw = width - private->width; + dh = height - private->height; + + private->x = x; + private->y = y; + + if (private->width != width || + private->height != height) + { + private->width = width; + private->height = height; + + old_pixmap = offscreen->pixmap; + offscreen->pixmap = gdk_pixmap_new (GDK_DRAWABLE (old_pixmap), + width, + height, + private->depth); + + gc = _gdk_drawable_get_scratch_gc (offscreen->pixmap, FALSE); + gdk_draw_drawable (offscreen->pixmap, + gc, + old_pixmap, + 0,0, 0, 0, + -1, -1); + g_object_unref (old_pixmap); + } + + if (GDK_WINDOW_IS_MAPPED (private)) + { + // TODO: Only invalidate new area, i.e. for larger windows + gdk_window_invalidate_rect (window, NULL, TRUE); + _gdk_synthesize_crossing_events_for_geometry_change (window); + } +} + +static void +gdk_offscreen_window_move_resize (GdkWindow *window, + gboolean with_move, + gint x, + gint y, + gint width, + gint height) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkOffscreenWindow *offscreen; + + offscreen = GDK_OFFSCREEN_WINDOW (private->impl); + + if (!with_move) + { + x = private->x; + y = private->y; + } + + if (width < 0) + width = private->width; + + if (height < 0) + height = private->height; + + gdk_offscreen_window_move_resize_internal (window, x, y, + width, height, + TRUE); +} + +static void +gdk_offscreen_window_show (GdkWindow *window, + gboolean already_mapped) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + + gdk_window_clear_area_e (window, 0, 0, + private->width, private->height); +} + + +static void +gdk_offscreen_window_hide (GdkWindow *window) +{ + GdkWindowObject *private; + GdkOffscreenWindow *offscreen; + GdkDisplay *display; + + g_return_if_fail (window != NULL); + + private = (GdkWindowObject*) window; + offscreen = GDK_OFFSCREEN_WINDOW (private->impl); + + /* May need to break grabs on children */ + display = gdk_drawable_get_display (window); + + /* TODO: This needs updating to the new grab world */ +#if 0 + if (display->pointer_grab.window != NULL) + { + if (is_parent_of (window, display->pointer_grab.window)) + { + /* Call this ourselves, even though gdk_display_pointer_ungrab + does so too, since we want to pass implicit == TRUE so the + broken grab event is generated */ + _gdk_display_unset_has_pointer_grab (display, + TRUE, + FALSE, + GDK_CURRENT_TIME); + gdk_display_pointer_ungrab (display, GDK_CURRENT_TIME); + } + } +#endif +} + +static void +gdk_offscreen_window_withdraw (GdkWindow *window) +{ +} + +static GdkEventMask +gdk_offscreen_window_get_events (GdkWindow *window) +{ + return 0; +} + +static void +gdk_offscreen_window_set_events (GdkWindow *window, + GdkEventMask event_mask) +{ +} + +static void +gdk_offscreen_window_set_background (GdkWindow *window, + const GdkColor *color) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkColormap *colormap = gdk_drawable_get_colormap (window); + + private->bg_color = *color; + gdk_colormap_query_color (colormap, private->bg_color.pixel, &private->bg_color); + + if (private->bg_pixmap && + private->bg_pixmap != GDK_PARENT_RELATIVE_BG && + private->bg_pixmap != GDK_NO_BG) + g_object_unref (private->bg_pixmap); + + private->bg_pixmap = NULL; +} + +static void +gdk_offscreen_window_set_back_pixmap (GdkWindow *window, + GdkPixmap *pixmap) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + + if (pixmap && + private->bg_pixmap != GDK_PARENT_RELATIVE_BG && + private->bg_pixmap != GDK_NO_BG && + !gdk_drawable_get_colormap (pixmap)) + { + g_warning ("gdk_window_set_back_pixmap(): pixmap must have a colormap"); + return; + } + + if (private->bg_pixmap && + private->bg_pixmap != GDK_PARENT_RELATIVE_BG && + private->bg_pixmap != GDK_NO_BG) + g_object_unref (private->bg_pixmap); + + private->bg_pixmap = pixmap; + + if (pixmap && + private->bg_pixmap != GDK_PARENT_RELATIVE_BG && + private->bg_pixmap != GDK_NO_BG) + g_object_ref (pixmap); +} + +static void +gdk_offscreen_window_shape_combine_region (GdkWindow *window, + const GdkRegion *shape_region, + gint offset_x, + gint offset_y) +{ +} + +static void +gdk_offscreen_window_input_shape_combine_region (GdkWindow *window, + const GdkRegion *shape_region, + gint offset_x, + gint offset_y) +{ +} + +static gboolean +gdk_offscreen_window_set_static_gravities (GdkWindow *window, + gboolean use_static) +{ + return TRUE; +} + +static void +gdk_offscreen_window_set_cursor (GdkWindow *window, + GdkCursor *cursor) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkOffscreenWindow *offscreen; + + offscreen = GDK_OFFSCREEN_WINDOW (private->impl); + + if (offscreen->cursor) + { + gdk_cursor_unref (offscreen->cursor); + offscreen->cursor = NULL; + } + + if (cursor) + offscreen->cursor = gdk_cursor_ref (cursor); + + /* TODO: The cursor is never actually used... */ +} + +static void +gdk_offscreen_window_get_geometry (GdkWindow *window, + gint *x, + gint *y, + gint *width, + gint *height, + gint *depth) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + + g_return_if_fail (window == NULL || GDK_IS_WINDOW (window)); + + if (!GDK_WINDOW_DESTROYED (window)) + { + if (x) + *x = private->x; + if (y) + *y = private->y; + if (width) + *width = private->width; + if (height) + *height = private->height; + if (depth) + *depth = private->depth; + } +} + +static gboolean +gdk_offscreen_window_queue_antiexpose (GdkWindow *window, + GdkRegion *area) +{ + return FALSE; +} + +static void +gdk_offscreen_window_queue_translation (GdkWindow *window, + GdkGC *gc, + GdkRegion *area, + gint dx, + gint dy) +{ +} + +/** + * gdk_offscreen_window_set_embedder: + * @window: a #GdkWindow + * @embedder: the #GdkWindow that @window gets embedded in + * + * Sets @window to be embedded in @embedder. + * + * To fully embed an offscreen window, in addition to calling this + * function, it is also necessary to handle the #GdkWindow::pick-embedded-child + * signal on the @embedder and the #GdkWindow::to-embedder and + * #GdkWindow::from-embedder signals on @window. + * + * Since: 2.18 + */ +void +gdk_offscreen_window_set_embedder (GdkWindow *window, + GdkWindow *embedder) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkOffscreenWindow *offscreen; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + if (!GDK_IS_OFFSCREEN_WINDOW (private->impl)) + return; + + offscreen = GDK_OFFSCREEN_WINDOW (private->impl); + + if (embedder) + { + g_object_ref (embedder); + GDK_WINDOW_OBJECT (embedder)->num_offscreen_children++; + } + + if (offscreen->embedder) + { + g_object_unref (offscreen->embedder); + GDK_WINDOW_OBJECT (offscreen->embedder)->num_offscreen_children--; + } + + offscreen->embedder = embedder; +} + +/** + * gdk_offscreen_window_get_embedder: + * @window: a #GdkWindow + * + * Gets the window that @window is embedded in. + * + * Returns: the embedding #GdkWindow, or %NULL if @window is not an + * embedded offscreen window + * + * Since: 2.18 + */ +GdkWindow * +gdk_offscreen_window_get_embedder (GdkWindow *window) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkOffscreenWindow *offscreen; + + g_return_val_if_fail (GDK_IS_WINDOW (window), NULL); + + if (!GDK_IS_OFFSCREEN_WINDOW (private->impl)) + return NULL; + + offscreen = GDK_OFFSCREEN_WINDOW (private->impl); + + return offscreen->embedder; +} + +static void +gdk_offscreen_window_class_init (GdkOffscreenWindowClass *klass) +{ + GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = gdk_offscreen_window_finalize; + + drawable_class->create_gc = gdk_offscreen_window_create_gc; + drawable_class->_copy_to_image = gdk_offscreen_window_copy_to_image; + drawable_class->ref_cairo_surface = gdk_offscreen_window_ref_cairo_surface; + drawable_class->set_colormap = gdk_offscreen_window_set_colormap; + drawable_class->get_colormap = gdk_offscreen_window_get_colormap; + drawable_class->get_depth = gdk_offscreen_window_get_depth; + drawable_class->get_screen = gdk_offscreen_window_get_screen; + drawable_class->get_visual = gdk_offscreen_window_get_visual; + drawable_class->get_source_drawable = gdk_offscreen_window_get_source_drawable; + drawable_class->get_composite_drawable = gdk_offscreen_window_get_composite_drawable; + + drawable_class->draw_rectangle = gdk_offscreen_window_draw_rectangle; + drawable_class->draw_arc = gdk_offscreen_window_draw_arc; + drawable_class->draw_polygon = gdk_offscreen_window_draw_polygon; + drawable_class->draw_text = gdk_offscreen_window_draw_text; + drawable_class->draw_text_wc = gdk_offscreen_window_draw_text_wc; + drawable_class->draw_drawable_with_src = gdk_offscreen_window_draw_drawable; + drawable_class->draw_points = gdk_offscreen_window_draw_points; + drawable_class->draw_segments = gdk_offscreen_window_draw_segments; + drawable_class->draw_lines = gdk_offscreen_window_draw_lines; + drawable_class->draw_image = gdk_offscreen_window_draw_image; + drawable_class->draw_pixbuf = gdk_offscreen_window_draw_pixbuf; +} + +static void +gdk_offscreen_window_impl_iface_init (GdkWindowImplIface *iface) +{ + iface->show = gdk_offscreen_window_show; + iface->hide = gdk_offscreen_window_hide; + iface->withdraw = gdk_offscreen_window_withdraw; + iface->raise = gdk_offscreen_window_raise; + iface->lower = gdk_offscreen_window_lower; + iface->move_resize = gdk_offscreen_window_move_resize; + iface->set_background = gdk_offscreen_window_set_background; + iface->set_back_pixmap = gdk_offscreen_window_set_back_pixmap; + iface->get_events = gdk_offscreen_window_get_events; + iface->set_events = gdk_offscreen_window_set_events; + iface->reparent = gdk_offscreen_window_reparent; + iface->set_cursor = gdk_offscreen_window_set_cursor; + iface->get_geometry = gdk_offscreen_window_get_geometry; + iface->shape_combine_region = gdk_offscreen_window_shape_combine_region; + iface->input_shape_combine_region = gdk_offscreen_window_input_shape_combine_region; + iface->set_static_gravities = gdk_offscreen_window_set_static_gravities; + iface->queue_antiexpose = gdk_offscreen_window_queue_antiexpose; + iface->queue_translation = gdk_offscreen_window_queue_translation; + iface->get_root_coords = gdk_offscreen_window_get_root_coords; + iface->get_deskrelative_origin = gdk_offscreen_window_get_deskrelative_origin; + iface->get_pointer = gdk_offscreen_window_get_pointer; + iface->destroy = gdk_offscreen_window_destroy; +} + +#define __GDK_OFFSCREEN_WINDOW_C__ +#include "gdkaliasdef.c" diff --git a/gdk/gdkpango.c b/gdk/gdkpango.c index a38640374b..24efca8b29 100644 --- a/gdk/gdkpango.c +++ b/gdk/gdkpango.c @@ -214,7 +214,8 @@ get_cairo_context (GdkPangoRenderer *gdk_renderer, priv->cr, color, priv->stipple[part], - priv->gc_changed); + priv->gc_changed, + priv->drawable); } priv->last_part = part; diff --git a/gdk/gdkpixmap.c b/gdk/gdkpixmap.c index c717b9afb8..919a20252f 100644 --- a/gdk/gdkpixmap.c +++ b/gdk/gdkpixmap.c @@ -77,7 +77,8 @@ static void gdk_pixmap_draw_drawable (GdkDrawable *drawable, gint xdest, gint ydest, gint width, - gint height); + gint height, + GdkPixmap *original_src); static void gdk_pixmap_draw_points (GdkDrawable *drawable, GdkGC *gc, GdkPoint *points, @@ -145,6 +146,9 @@ static GdkImage* gdk_pixmap_copy_to_image (GdkDrawable *drawable, gint height); static cairo_surface_t *gdk_pixmap_ref_cairo_surface (GdkDrawable *drawable); +static cairo_surface_t *gdk_pixmap_create_cairo_surface (GdkDrawable *drawable, + int width, + int height); static GdkVisual* gdk_pixmap_real_get_visual (GdkDrawable *drawable); static gint gdk_pixmap_real_get_depth (GdkDrawable *drawable); @@ -199,7 +203,7 @@ gdk_pixmap_class_init (GdkPixmapObjectClass *klass) drawable_class->draw_polygon = gdk_pixmap_draw_polygon; drawable_class->draw_text = gdk_pixmap_draw_text; drawable_class->draw_text_wc = gdk_pixmap_draw_text_wc; - drawable_class->draw_drawable = gdk_pixmap_draw_drawable; + drawable_class->draw_drawable_with_src = gdk_pixmap_draw_drawable; drawable_class->draw_points = gdk_pixmap_draw_points; drawable_class->draw_segments = gdk_pixmap_draw_segments; drawable_class->draw_lines = gdk_pixmap_draw_lines; @@ -216,6 +220,7 @@ gdk_pixmap_class_init (GdkPixmapObjectClass *klass) drawable_class->get_visual = gdk_pixmap_real_get_visual; drawable_class->_copy_to_image = gdk_pixmap_copy_to_image; drawable_class->ref_cairo_surface = gdk_pixmap_ref_cairo_surface; + drawable_class->create_cairo_surface = gdk_pixmap_create_cairo_surface; } static void @@ -229,6 +234,54 @@ gdk_pixmap_finalize (GObject *object) G_OBJECT_CLASS (parent_class)->finalize (object); } +GdkPixmap * +gdk_pixmap_new (GdkDrawable *drawable, + gint width, + gint height, + gint depth) +{ + GdkDrawable *source_drawable; + + if (drawable) + source_drawable = _gdk_drawable_get_source_drawable (drawable); + else + source_drawable = NULL; + return _gdk_pixmap_new (source_drawable, width, height, depth); +} + +GdkPixmap * +gdk_bitmap_create_from_data (GdkDrawable *drawable, + const gchar *data, + gint width, + gint height) +{ + GdkDrawable *source_drawable; + + if (drawable) + source_drawable = _gdk_drawable_get_source_drawable (drawable); + else + source_drawable = NULL; + return _gdk_bitmap_create_from_data (source_drawable, data, width, height); +} + +GdkPixmap* +gdk_pixmap_create_from_data (GdkDrawable *drawable, + const gchar *data, + gint width, + gint height, + gint depth, + const GdkColor *fg, + const GdkColor *bg) +{ + GdkDrawable *source_drawable; + + source_drawable = _gdk_drawable_get_source_drawable (drawable); + return _gdk_pixmap_create_from_data (source_drawable, + data, width, height, + depth, fg,bg); +} + + static GdkGC * gdk_pixmap_create_gc (GdkDrawable *drawable, GdkGCValues *values, @@ -249,6 +302,7 @@ gdk_pixmap_draw_rectangle (GdkDrawable *drawable, { GdkPixmapObject *private = (GdkPixmapObject *)drawable; + _gdk_gc_remove_drawable_clip (gc); gdk_draw_rectangle (private->impl, gc, filled, x, y, width, height); } @@ -266,6 +320,7 @@ gdk_pixmap_draw_arc (GdkDrawable *drawable, { GdkPixmapObject *private = (GdkPixmapObject *)drawable; + _gdk_gc_remove_drawable_clip (gc); gdk_draw_arc (private->impl, gc, filled, x, y, width, height, angle1, angle2); @@ -280,6 +335,7 @@ gdk_pixmap_draw_polygon (GdkDrawable *drawable, { GdkPixmapObject *private = (GdkPixmapObject *)drawable; + _gdk_gc_remove_drawable_clip (gc); gdk_draw_polygon (private->impl, gc, filled, points, npoints); } @@ -294,6 +350,7 @@ gdk_pixmap_draw_text (GdkDrawable *drawable, { GdkPixmapObject *private = (GdkPixmapObject *)drawable; + _gdk_gc_remove_drawable_clip (gc); gdk_draw_text (private->impl, font, gc, x, y, text, text_length); } @@ -309,6 +366,7 @@ gdk_pixmap_draw_text_wc (GdkDrawable *drawable, { GdkPixmapObject *private = (GdkPixmapObject *)drawable; + _gdk_gc_remove_drawable_clip (gc); gdk_draw_text_wc (private->impl, font, gc, x, y, text, text_length); } @@ -322,13 +380,19 @@ gdk_pixmap_draw_drawable (GdkDrawable *drawable, gint xdest, gint ydest, gint width, - gint height) + gint height, + GdkPixmap *original_src) { GdkPixmapObject *private = (GdkPixmapObject *)drawable; - gdk_draw_drawable (private->impl, gc, src, xsrc, ysrc, - xdest, ydest, - width, height); + _gdk_gc_remove_drawable_clip (gc); + /* Call the method directly to avoid getting the composite drawable again */ + GDK_DRAWABLE_GET_CLASS (private->impl)->draw_drawable_with_src (private->impl, gc, + src, + xsrc, ysrc, + xdest, ydest, + width, height, + original_src); } static void @@ -339,6 +403,7 @@ gdk_pixmap_draw_points (GdkDrawable *drawable, { GdkPixmapObject *private = (GdkPixmapObject *)drawable; + _gdk_gc_remove_drawable_clip (gc); gdk_draw_points (private->impl, gc, points, npoints); } @@ -350,6 +415,7 @@ gdk_pixmap_draw_segments (GdkDrawable *drawable, { GdkPixmapObject *private = (GdkPixmapObject *)drawable; + _gdk_gc_remove_drawable_clip (gc); gdk_draw_segments (private->impl, gc, segs, nsegs); } @@ -361,6 +427,7 @@ gdk_pixmap_draw_lines (GdkDrawable *drawable, { GdkPixmapObject *private = (GdkPixmapObject *)drawable; + _gdk_gc_remove_drawable_clip (gc); gdk_draw_lines (private->impl, gc, points, npoints); } @@ -374,6 +441,7 @@ gdk_pixmap_draw_glyphs (GdkDrawable *drawable, { GdkPixmapObject *private = (GdkPixmapObject *)drawable; + _gdk_gc_remove_drawable_clip (gc); gdk_draw_glyphs (private->impl, gc, font, x, y, glyphs); } @@ -388,6 +456,7 @@ gdk_pixmap_draw_glyphs_transformed (GdkDrawable *drawable, { GdkPixmapObject *private = (GdkPixmapObject *)drawable; + _gdk_gc_remove_drawable_clip (gc); gdk_draw_glyphs_transformed (private->impl, gc, matrix, font, x, y, glyphs); } @@ -404,6 +473,7 @@ gdk_pixmap_draw_image (GdkDrawable *drawable, { GdkPixmapObject *private = (GdkPixmapObject *)drawable; + _gdk_gc_remove_drawable_clip (gc); gdk_draw_image (private->impl, gc, image, xsrc, ysrc, xdest, ydest, width, height); } @@ -424,6 +494,8 @@ gdk_pixmap_draw_pixbuf (GdkDrawable *drawable, { GdkPixmapObject *private = (GdkPixmapObject *)drawable; + if (gc) + _gdk_gc_remove_drawable_clip (gc); gdk_draw_pixbuf (private->impl, gc, pixbuf, src_x, src_y, dest_x, dest_y, width, height, dither, x_dither, y_dither); @@ -437,6 +509,7 @@ gdk_pixmap_draw_trapezoids (GdkDrawable *drawable, { GdkPixmapObject *private = (GdkPixmapObject *)drawable; + _gdk_gc_remove_drawable_clip (gc); gdk_draw_trapezoids (private->impl, gc, trapezoids, n_trapezoids); } @@ -515,6 +588,17 @@ gdk_pixmap_ref_cairo_surface (GdkDrawable *drawable) return _gdk_drawable_ref_cairo_surface (((GdkPixmapObject*)drawable)->impl); } +static cairo_surface_t * +gdk_pixmap_create_cairo_surface (GdkDrawable *drawable, + int width, + int height) +{ + return _gdk_windowing_create_cairo_surface (GDK_PIXMAP_OBJECT(drawable)->impl, + width, height); +} + + + static GdkBitmap * make_solid_mask (GdkScreen *screen, gint width, gint height) { diff --git a/gdk/gdkprivate.h b/gdk/gdkprivate.h index 031fe9ae7f..65038627a1 100644 --- a/gdk/gdkprivate.h +++ b/gdk/gdkprivate.h @@ -34,8 +34,10 @@ G_BEGIN_DECLS #define GDK_PARENT_RELATIVE_BG ((GdkPixmap *)1L) #define GDK_NO_BG ((GdkPixmap *)2L) -#define GDK_WINDOW_TYPE(d) (((GdkWindowObject*)(GDK_WINDOW (d)))->window_type) -#define GDK_WINDOW_DESTROYED(d) (((GdkWindowObject*)(GDK_WINDOW (d)))->destroyed) +#ifndef GDK_COMPILATION +#define GDK_WINDOW_TYPE(d) (gdk_window_get_window_type (GDK_WINDOW (d))) +#define GDK_WINDOW_DESTROYED(d) (gdk_window_is_destroyed (GDK_WINDOW (d))) +#endif void gdk_window_destroy_notify (GdkWindow *window); diff --git a/gdk/gdkregion-generic.c b/gdk/gdkregion-generic.c index f835ab7d6f..d98dc8822d 100644 --- a/gdk/gdkregion-generic.c +++ b/gdk/gdkregion-generic.c @@ -96,6 +96,7 @@ static void miRegionOp (GdkRegion *newReg, overlapFunc overlapFn, nonOverlapFunc nonOverlap1Fn, nonOverlapFunc nonOverlap2Fn); +static void miSetExtents (GdkRegion *pReg); /** * gdk_region_new: @@ -122,6 +123,31 @@ gdk_region_new (void) return temp; } +GdkRegion * +_gdk_region_new_from_yxbanded_rects (GdkRectangle *rects, + int num_rects) +{ + GdkRegion *temp; + int i; + + temp = g_slice_new (GdkRegion); + + temp->rects = g_new (GdkRegionBox, num_rects); + temp->size = num_rects; + temp->numRects = num_rects; + for (i = 0; i < num_rects; i++) + { + temp->rects[i].x1 = rects[i].x; + temp->rects[i].y1 = rects[i].y; + temp->rects[i].x2 = rects[i].x + rects[i].width; + temp->rects[i].y2 = rects[i].y + rects[i].height; + } + miSetExtents (temp); + + return temp; +} + + /** * gdk_region_rectangle: * @rectangle: a #GdkRectangle @@ -1555,6 +1581,32 @@ gdk_region_equal (const GdkRegion *region1, return TRUE; } +/** + * gdk_region_rect_equal: + * @region: a #GdkRegion + * @rectangle: a #GdkRectangle + * + * Finds out if a regions is the same as a rectangle. + * + * Returns: %TRUE if @region and @rectangle are equal. + * + * Since: 2.18 + */ +gboolean +gdk_region_rect_equal (const GdkRegion *region, + const GdkRectangle *rectangle) +{ + g_return_val_if_fail (region != NULL, FALSE); + g_return_val_if_fail (rectangle != NULL, FALSE); + + if (region->numRects != 1) return FALSE; + else if (region->extents.x1 != rectangle->x) return FALSE; + else if (region->extents.y1 != rectangle->y) return FALSE; + else if (region->extents.x2 != rectangle->x + rectangle->width) return FALSE; + else if (region->extents.y2 != rectangle->y + rectangle->height) return FALSE; + return TRUE; +} + /** * gdk_region_point_in: * @region: a #GdkRegion diff --git a/gdk/gdkregion.h b/gdk/gdkregion.h index b7381eaf4d..0adffa1a08 100644 --- a/gdk/gdkregion.h +++ b/gdk/gdkregion.h @@ -77,6 +77,8 @@ void gdk_region_get_rectangles (const GdkRegion *region, gboolean gdk_region_empty (const GdkRegion *region); gboolean gdk_region_equal (const GdkRegion *region1, const GdkRegion *region2); +gboolean gdk_region_rect_equal (const GdkRegion *region, + const GdkRectangle *rectangle); gboolean gdk_region_point_in (const GdkRegion *region, int x, int y); diff --git a/gdk/gdkscreen.h b/gdk/gdkscreen.h index b1f3b8e8a7..96ff8d44a2 100644 --- a/gdk/gdkscreen.h +++ b/gdk/gdkscreen.h @@ -51,6 +51,7 @@ struct _GdkScreen GdkGC *normal_gcs[32]; GdkGC *exposure_gcs[32]; + GdkGC *subwindow_gcs[32]; cairo_font_options_t *font_options; double resolution; /* pixels/points scale factor for fonts */ diff --git a/gdk/gdkselection.h b/gdk/gdkselection.h index 325c38321c..1a96214425 100644 --- a/gdk/gdkselection.h +++ b/gdk/gdkselection.h @@ -86,7 +86,7 @@ void gdk_selection_convert (GdkWindow *requestor, GdkAtom selection, GdkAtom target, guint32 time_); -gboolean gdk_selection_property_get (GdkWindow *requestor, +gint gdk_selection_property_get (GdkWindow *requestor, guchar **data, GdkAtom *prop_type, gint *prop_format); diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c index 76a2ec618d..7f3572f5b0 100644 --- a/gdk/gdkwindow.c +++ b/gdk/gdkwindow.c @@ -22,7 +22,7 @@ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS * file for a list of people on the GTK+ Team. See the ChangeLog * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. */ #include "config.h" @@ -32,12 +32,107 @@ #include "gdk.h" /* For gdk_rectangle_union() */ #include "gdkpixmap.h" #include "gdkdrawable.h" +#include "gdkintl.h" #include "gdkscreen.h" +#include "gdkmarshalers.h" #include "gdkalias.h" +#undef DEBUG_WINDOW_PRINTING + +#ifdef GDK_WINDOWING_X11 +#include "x11/gdkx.h" /* For workaround */ +#endif + +#include "math.h" + +/* Historically a GdkWindow always matches a platform native window, + * be it a toplevel window or a child window. In this setup the + * GdkWindow (and other GdkDrawables) were platform independent classes, + * and the actual platform specific implementation was in a delegate + * object availible as "impl" in the window object. + * + * With the addition of client side windows and offscreen windows this + * changes a bit. The application-visible GdkWindow object behaves as + * it did before, but not all such windows now have a corresponding native + * window. Instead windows that are "client side" are emulated by the gdk + * code such that clipping, drawing, moving, events etc work as expected. + * + * For GdkWindows that have a native window the "impl" object is the + * same as before. However, for all client side windows the impl object + * is shared with its parent (i.e. all client windows descendants of one + * native window has the same impl. + * + * Additionally there is a new type of platform independent impl object, + * GdkOffscreenWindow. All windows of type GDK_WINDOW_OFFSCREEN get an impl + * of this type (while their children are generally GDK_WINDOW_CHILD virtual + * windows). Such windows work by allocating a GdkPixmap as the backing store + * for drawing operations, which is resized with the window. + * + * GdkWindows have a pointer to the "impl window" they are in, i.e. + * the topmost GdkWindow which have the same "impl" value. This is stored + * in impl_window, which is different from the window itself only for client + * side windows. + * All GdkWindows (native or not) track the position of the window in the parent + * (x, y), the size of the window (width, height), the position of the window + * with respect to the impl window (abs_x, abs_y). We also track the clip + * region of the window wrt parent windows and siblings, in window-relative + * coordinates with and without child windows included (clip_region, + * clip_region_with_children). + * + * All toplevel windows are native windows, but also child windows can be + * native (although not children of offscreens). We always listen to + * a basic set of events (see get_native_event_mask) for these windows + * so that we can emulate events for any client side children. + * + * For native windows we apply the calculated clip region as a window shape + * so that eg. client side siblings that overlap the native child properly + * draws over the native child window. + * + * In order to minimize flicker and for performance we use a couple of cacheing + * tricks. First of all, every time we do a window to window copy area, for instance + * when moving a client side window or when scrolling/moving a region in a window + * we store this in outstanding_moves instead of applying immediately. We then + * delay this move until we really need it (because something depends on being + * able to read it), or until we're handing a redraw from an expose/invalidation + * (actually we delay it past redraw, but before blitting the double buffer pixmap + * to the window). This gives us two advantages. First of all it minimizes the time + * from the window is moved to the exposes related to that move, secondly it allows + * us to be smart about how to do the copy. We combine multiple moves into one (when + * possible) and we don't actually do copies to anything that is or will be + * invalidated and exposed anyway. + * + * Secondly, we use something called a "implicit paint" during repaint handling. + * An implicit paint is similar to a regular paint for the paint stack, but it is + * not put on the stack. Instead, it is set on the impl window, and later when + * regular gdk_window_begin_paint_region() happen on a window of this impl window + * we reuse the pixmap from the implicit paint. During repaint we create and at the + * end flush an implicit paint, which means we can collect all the paints on + * multiple client side windows in the same backing store pixmap. + * + * All drawing to windows are wrapped with macros that set up the GC such that + * the offsets and clip region is right for drawing to the paint object or + * directly to the emulated window. It also automatically handles any flushing + * needed when drawing directly to a window. Adding window/paint clipping is + * done using _gdk_gc_add_drawable_clip which lets us efficiently add and then + * remove a custom clip region. + */ + #define USE_BACKING_STORE /* Appears to work on Win32, too, now. */ -typedef struct _GdkWindowPaint GdkWindowPaint; +/* This adds a local value to the GdkVisibilityState enum */ +#define GDK_VISIBILITY_NOT_VIEWABLE 3 + +enum { + PICK_EMBEDDED_CHILD, /* only called if children are embedded */ + TO_EMBEDDER, + FROM_EMBEDDER, + LAST_SIGNAL +}; + +enum { + PROP_0, + PROP_CURSOR +}; struct _GdkWindowPaint { @@ -46,83 +141,75 @@ struct _GdkWindowPaint gint x_offset; gint y_offset; cairo_surface_t *surface; + guint uses_implicit : 1; + guint flushed : 1; + guint32 region_tag; }; typedef struct { - GdkRegion *old_region; - gint old_clip_x_origin; - gint old_clip_y_origin; - gint x_offset; - gint y_offset; -} GdkWindowClipData; + GdkRegion *dest_region; /* The destination region */ + int dx, dy; /* The amount that the source was moved to reach dest_region */ +} GdkWindowRegionMove; -struct _GdkWindowRedirect -{ - GdkWindowObject *redirected; - GdkDrawable *pixmap; - gint src_x; - gint src_y; - gint dest_x; - gint dest_y; - gint width; - gint height; -}; + +/* Global info */ static GdkGC *gdk_window_create_gc (GdkDrawable *drawable, - GdkGCValues *values, - GdkGCValuesMask mask); + GdkGCValues *values, + GdkGCValuesMask mask); static void gdk_window_draw_rectangle (GdkDrawable *drawable, - GdkGC *gc, - gboolean filled, - gint x, - gint y, - gint width, - gint height); + GdkGC *gc, + gboolean filled, + gint x, + gint y, + gint width, + gint height); static void gdk_window_draw_arc (GdkDrawable *drawable, - GdkGC *gc, - gboolean filled, - gint x, - gint y, - gint width, - gint height, - gint angle1, - gint angle2); + GdkGC *gc, + gboolean filled, + gint x, + gint y, + gint width, + gint height, + gint angle1, + gint angle2); static void gdk_window_draw_polygon (GdkDrawable *drawable, - GdkGC *gc, - gboolean filled, - GdkPoint *points, - gint npoints); + GdkGC *gc, + gboolean filled, + GdkPoint *points, + gint npoints); static void gdk_window_draw_text (GdkDrawable *drawable, - GdkFont *font, - GdkGC *gc, - gint x, - gint y, - const gchar *text, - gint text_length); + GdkFont *font, + GdkGC *gc, + gint x, + gint y, + const gchar *text, + gint text_length); static void gdk_window_draw_text_wc (GdkDrawable *drawable, - GdkFont *font, - GdkGC *gc, - gint x, - gint y, - const GdkWChar *text, - gint text_length); + GdkFont *font, + GdkGC *gc, + gint x, + gint y, + const GdkWChar *text, + gint text_length); static void gdk_window_draw_drawable (GdkDrawable *drawable, - GdkGC *gc, - GdkPixmap *src, - gint xsrc, - gint ysrc, - gint xdest, - gint ydest, - gint width, - gint height); + GdkGC *gc, + GdkPixmap *src, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height, + GdkDrawable *original_src); static void gdk_window_draw_points (GdkDrawable *drawable, - GdkGC *gc, - GdkPoint *points, - gint npoints); + GdkGC *gc, + GdkPoint *points, + gint npoints); static void gdk_window_draw_segments (GdkDrawable *drawable, - GdkGC *gc, - GdkSegment *segs, - gint nsegs); + GdkGC *gc, + GdkSegment *segs, + gint nsegs); static void gdk_window_draw_lines (GdkDrawable *drawable, GdkGC *gc, GdkPoint *points, @@ -143,14 +230,14 @@ static void gdk_window_draw_glyphs_transformed (GdkDrawable *drawable, PangoGlyphString *glyphs); static void gdk_window_draw_image (GdkDrawable *drawable, - GdkGC *gc, - GdkImage *image, - gint xsrc, - gint ysrc, - gint xdest, - gint ydest, - gint width, - gint height); + GdkGC *gc, + GdkImage *image, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height); static void gdk_window_draw_pixbuf (GdkDrawable *drawable, GdkGC *gc, @@ -180,10 +267,15 @@ static GdkImage* gdk_window_copy_to_image (GdkDrawable *drawable, gint height); static cairo_surface_t *gdk_window_ref_cairo_surface (GdkDrawable *drawable); +static cairo_surface_t *gdk_window_create_cairo_surface (GdkDrawable *drawable, + int width, + int height); +static void gdk_window_set_cairo_clip (GdkDrawable *drawable, + cairo_t *cr); static void gdk_window_real_get_size (GdkDrawable *drawable, - gint *width, - gint *height); + gint *width, + gint *height); static GdkVisual* gdk_window_real_get_visual (GdkDrawable *drawable); static gint gdk_window_real_get_depth (GdkDrawable *drawable); @@ -192,6 +284,7 @@ static void gdk_window_real_set_colormap (GdkDrawable *drawable, GdkColormap *cmap); static GdkColormap* gdk_window_real_get_colormap (GdkDrawable *drawable); +static GdkDrawable* gdk_window_get_source_drawable (GdkDrawable *drawable); static GdkDrawable* gdk_window_get_composite_drawable (GdkDrawable *drawable, gint x, gint y, @@ -207,31 +300,53 @@ static void gdk_window_free_paint_stack (GdkWindow *window); static void gdk_window_init (GdkWindowObject *window); static void gdk_window_class_init (GdkWindowObjectClass *klass); static void gdk_window_finalize (GObject *object); -static void gdk_window_clear_backing_rect (GdkWindow *window, - gint x, - gint y, - gint width, - gint height); -static void setup_redirect_clip (GdkWindow *window, - GdkGC *gc, - GdkWindowClipData *data); -static void reset_redirect_clip (GdkWindow *offscreen, - GdkGC *gc, - GdkWindowClipData *data); + +static void gdk_window_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void gdk_window_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); + +static void gdk_window_clear_backing_region (GdkWindow *window, + GdkRegion *region); static void gdk_window_redirect_free (GdkWindowRedirect *redirect); static void apply_redirect_to_children (GdkWindowObject *private, GdkWindowRedirect *redirect); static void remove_redirect_from_children (GdkWindowObject *private, GdkWindowRedirect *redirect); -static GdkRegion *_gdk_window_calculate_full_clip_region (GdkWindow *window, - GdkWindow *base_window, - GdkGC *gc, - gboolean do_children, - gint *base_x_offset, - gint *base_y_offset); + +static void recompute_visible_regions (GdkWindowObject *private, + gboolean recalculate_siblings, + gboolean recalculate_children); +static void gdk_window_flush_outstanding_moves (GdkWindow *window); +static void gdk_window_flush_recursive (GdkWindowObject *window); +static void do_move_region_bits_on_impl (GdkWindowObject *private, + GdkRegion *region, /* In impl window coords */ + int dx, int dy); +static void gdk_window_invalidate_in_parent (GdkWindowObject *private); +static void move_native_children (GdkWindowObject *private); +static void update_cursor (GdkDisplay *display); +static void impl_window_add_update_area (GdkWindowObject *impl_window, + GdkRegion *region); +static void gdk_window_region_move_free (GdkWindowRegionMove *move); + +static guint signals[LAST_SIGNAL] = { 0 }; static gpointer parent_class = NULL; +static const cairo_user_data_key_t gdk_window_cairo_key; + +static guint32 +new_region_tag (void) +{ + static guint32 tag = 0; + + return ++tag; +} + GType gdk_window_object_get_type (void) { @@ -245,7 +360,7 @@ gdk_window_object_get_type (void) sizeof (GdkWindowObject), (GInstanceInitFunc) gdk_window_init, 0); - + return object_type; } @@ -281,6 +396,26 @@ gdk_window_init (GdkWindowObject *window) window->window_type = GDK_WINDOW_CHILD; window->state = GDK_WINDOW_STATE_WITHDRAWN; + window->width = 1; + window->height = 1; + window->toplevel_window_type = -1; + /* starts hidden */ + window->effective_visibility = GDK_VISIBILITY_NOT_VIEWABLE; + window->visibility = GDK_VISIBILITY_FULLY_OBSCURED; + /* Default to unobscured since some backends don't send visibility events */ + window->native_visibility = GDK_VISIBILITY_UNOBSCURED; +} + +/* Stop and return on the first non-NULL parent */ +static gboolean +accumulate_get_window (GSignalInvocationHint *ihint, + GValue *return_accu, + const GValue *handler_return, + gpointer data) +{ + g_value_copy (handler_return, return_accu); + /* Continue while returning NULL */ + return g_value_get_object (handler_return) == NULL; } static GQuark quark_pointer_window = 0; @@ -290,10 +425,12 @@ gdk_window_class_init (GdkWindowObjectClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass); - + parent_class = g_type_class_peek_parent (klass); object_class->finalize = gdk_window_finalize; + object_class->set_property = gdk_window_set_property; + object_class->get_property = gdk_window_get_property; drawable_class->create_gc = gdk_window_create_gc; drawable_class->draw_rectangle = gdk_window_draw_rectangle; @@ -301,7 +438,7 @@ gdk_window_class_init (GdkWindowObjectClass *klass) drawable_class->draw_polygon = gdk_window_draw_polygon; drawable_class->draw_text = gdk_window_draw_text; drawable_class->draw_text_wc = gdk_window_draw_text_wc; - drawable_class->draw_drawable = gdk_window_draw_drawable; + drawable_class->draw_drawable_with_src = gdk_window_draw_drawable; drawable_class->draw_points = gdk_window_draw_points; drawable_class->draw_segments = gdk_window_draw_segments; drawable_class->draw_lines = gdk_window_draw_lines; @@ -318,11 +455,107 @@ gdk_window_class_init (GdkWindowObjectClass *klass) drawable_class->get_visual = gdk_window_real_get_visual; drawable_class->_copy_to_image = gdk_window_copy_to_image; drawable_class->ref_cairo_surface = gdk_window_ref_cairo_surface; + drawable_class->create_cairo_surface = gdk_window_create_cairo_surface; + drawable_class->set_cairo_clip = gdk_window_set_cairo_clip; drawable_class->get_clip_region = gdk_window_get_clip_region; drawable_class->get_visible_region = gdk_window_get_visible_region; drawable_class->get_composite_drawable = gdk_window_get_composite_drawable; + drawable_class->get_source_drawable = gdk_window_get_source_drawable; quark_pointer_window = g_quark_from_static_string ("gtk-pointer-window"); + + + /* Properties */ + g_object_class_install_property (object_class, + PROP_CURSOR, + g_param_spec_boxed ("cursor", + P_("Cursor"), + P_("Cursor"), + GDK_TYPE_CURSOR, + G_PARAM_READWRITE)); + + /** + * GdkWindow::pick-embedded-child: + * @window: the window on which the signal is emitted + * @x: x coordinate in the window + * @y: y coordinate in the window + * + * The ::pick-embedded-child signal is emitted to find an embedded + * child at the given position. + * + * Returns: the #GdkWindow of the embedded child at @x, @y, or %NULL + * + * Since: 2.18 + */ + signals[PICK_EMBEDDED_CHILD] = + g_signal_new (g_intern_static_string ("pick-embedded-child"), + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + 0, + accumulate_get_window, NULL, + _gdk_marshal_OBJECT__DOUBLE_DOUBLE, + GDK_TYPE_WINDOW, + 2, + G_TYPE_DOUBLE, + G_TYPE_DOUBLE); + + /** + * GdkWindow::to-embedder: + * @window: the offscreen window on which the signal is emitted + * @offscreen-x: x coordinate in the offscreen window + * @offscreen-y: y coordinate in the offscreen window + * @embedder-x: return location for the x coordinate in the embedder window + * @embedder-y: return location for the y coordinate in the embedder window + * + * The ::to-embedder signal is emitted to translate coordinates + * in an offscreen window to its embedder. + * + * See also #GtkWindow::from-embedder. + * + * Since: 2.18 + */ + signals[TO_EMBEDDER] = + g_signal_new (g_intern_static_string ("to-embedder"), + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + _gdk_marshal_VOID__DOUBLE_DOUBLE_POINTER_POINTER, + G_TYPE_NONE, + 4, + G_TYPE_DOUBLE, + G_TYPE_DOUBLE, + G_TYPE_POINTER, + G_TYPE_POINTER); + + /** + * GdkWindow::from-embedder: + * @window: the offscreen window on which the signal is emitted + * @embedder-x: x coordinate in the embedder window + * @embedder-y: y coordinate in the embedder window + * @offscreen-x: return location for the x coordinate in the offscreen window + * @offscreen-y: return location for the y coordinate in the offscreen window + * + * The ::from-embedder signal is emitted to translate coordinates + * in the embedder of an offscreen window to the offscreen window. + * + * See also #GtkWindow::to-embedder. + * + * Since: 2.18 + */ + signals[FROM_EMBEDDER] = + g_signal_new (g_intern_static_string ("from-embedder"), + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + _gdk_marshal_VOID__DOUBLE_DOUBLE_POINTER_POINTER, + G_TYPE_NONE, + 4, + G_TYPE_DOUBLE, + G_TYPE_DOUBLE, + G_TYPE_POINTER, + G_TYPE_POINTER); } static void @@ -330,7 +563,7 @@ gdk_window_finalize (GObject *object) { GdkWindow *window = GDK_WINDOW (object); GdkWindowObject *obj = (GdkWindowObject *) object; - + if (!GDK_WINDOW_DESTROYED (window)) { if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN) @@ -345,24 +578,686 @@ gdk_window_finalize (GObject *object) _gdk_window_destroy (window, TRUE); } - g_object_unref (obj->impl); - obj->impl = NULL; - + if (obj->impl) + { + g_object_unref (obj->impl); + obj->impl = NULL; + } + + if (obj->impl_window != obj) + { + g_object_unref (obj->impl_window); + obj->impl_window = NULL; + } + + if (obj->shape) + gdk_region_destroy (obj->shape); + + if (obj->input_shape) + gdk_region_destroy (obj->input_shape); + + if (obj->cursor) + gdk_cursor_unref (obj->cursor); + G_OBJECT_CLASS (parent_class)->finalize (object); } +static void +gdk_window_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GdkWindow *window = (GdkWindow *)object; + + switch (prop_id) + { + case PROP_CURSOR: + gdk_window_set_cursor (window, g_value_get_boxed (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gdk_window_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GdkWindow *window = (GdkWindow *) object; + + switch (prop_id) + { + case PROP_CURSOR: + g_value_set_boxed (value, gdk_window_get_cursor (window)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static gboolean +gdk_window_is_offscreen (GdkWindowObject *window) +{ + return window->window_type == GDK_WINDOW_OFFSCREEN; +} + +static GdkWindowObject * +gdk_window_get_impl_window (GdkWindowObject *window) +{ + return window->impl_window; +} + +GdkWindow * +_gdk_window_get_impl_window (GdkWindow *window) +{ + return (GdkWindow *)gdk_window_get_impl_window ((GdkWindowObject *)window); +} + +static gboolean +gdk_window_has_impl (GdkWindowObject *window) +{ + return window->impl_window == window; +} + +static gboolean +gdk_window_is_toplevel (GdkWindowObject *window) +{ + return + window->parent == NULL || + window->parent->window_type == GDK_WINDOW_ROOT; +} + +gboolean +_gdk_window_has_impl (GdkWindow *window) +{ + return gdk_window_has_impl ((GdkWindowObject *)window); +} + +static gboolean +gdk_window_has_no_impl (GdkWindowObject *window) +{ + return window->impl_window != window; +} + +static void +remove_child_area (GdkWindowObject *private, + GdkWindowObject *until, + gboolean for_input, + GdkRegion *region) +{ + GdkWindowObject *child; + GdkRegion *child_region; + GdkRectangle r; + GList *l; + GdkRegion *shape; + + for (l = private->children; l; l = l->next) + { + child = l->data; + + if (child == until) + break; + + /* If region is empty already, no need to do + anything potentially costly */ + if (gdk_region_empty (region)) + break; + + if (!GDK_WINDOW_IS_MAPPED (child) || child->input_only || child->composited) + continue; + + /* Ignore offscreen children, as they don't draw in their parent and + * don't take part in the clipping */ + if (gdk_window_is_offscreen (child)) + continue; + + r.x = child->x; + r.y = child->y; + r.width = child->width; + r.height = child->height; + + /* Bail early if child totally outside region */ + if (gdk_region_rect_in (region, &r) == GDK_OVERLAP_RECTANGLE_OUT) + continue; + + child_region = gdk_region_rectangle (&r); + + if (child->shape) + { + /* Adjust shape region to parent window coords */ + gdk_region_offset (child->shape, child->x, child->y); + gdk_region_intersect (child_region, child->shape); + gdk_region_offset (child->shape, -child->x, -child->y); + } + else if (private->window_type == GDK_WINDOW_FOREIGN) + { + shape = _gdk_windowing_window_get_shape ((GdkWindow *)child); + if (shape) + { + gdk_region_intersect (child_region, shape); + gdk_region_destroy (shape); + } + } + + if (for_input) + { + if (child->input_shape) + gdk_region_intersect (child_region, child->input_shape); + else if (private->window_type == GDK_WINDOW_FOREIGN) + { + shape = _gdk_windowing_window_get_input_shape ((GdkWindow *)child); + if (shape) + { + gdk_region_intersect (child_region, shape); + gdk_region_destroy (shape); + } + } + } + + gdk_region_subtract (region, child_region); + gdk_region_destroy (child_region); + + } +} + +static GdkVisibilityState +effective_visibility (GdkWindowObject *private) +{ + GdkVisibilityState native; + + if (!gdk_window_is_viewable ((GdkWindow *)private)) + return GDK_VISIBILITY_NOT_VIEWABLE; + + native = private->impl_window->native_visibility; + + if (native == GDK_VISIBILITY_FULLY_OBSCURED || + private->visibility == GDK_VISIBILITY_FULLY_OBSCURED) + return GDK_VISIBILITY_FULLY_OBSCURED; + else if (native == GDK_VISIBILITY_UNOBSCURED) + return private->visibility; + else /* native PARTIAL, private partial or unobscured */ + return GDK_VISIBILITY_PARTIAL; +} + +static void +gdk_window_update_visibility (GdkWindowObject *private) +{ + GdkVisibilityState new_visibility; + GdkEvent *event; + + new_visibility = effective_visibility (private); + + if (new_visibility != private->effective_visibility) + { + private->effective_visibility = new_visibility; + + if (new_visibility != GDK_VISIBILITY_NOT_VIEWABLE && + private->event_mask & GDK_VISIBILITY_NOTIFY) + { + event = _gdk_make_event ((GdkWindow *)private, GDK_VISIBILITY_NOTIFY, + NULL, FALSE); + event->visibility.state = new_visibility; + } + } +} + +static void +gdk_window_update_visibility_recursively (GdkWindowObject *private, + GdkWindowObject *only_for_impl) +{ + GdkWindowObject *child; + GList *l; + + gdk_window_update_visibility (private); + for (l = private->children; l != NULL; l = l->next) + { + child = l->data; + if ((only_for_impl == NULL) || + (only_for_impl == child->impl_window)) + gdk_window_update_visibility_recursively (child, only_for_impl); + } +} + +static gboolean +should_apply_clip_as_shape (GdkWindowObject *private) +{ + return + gdk_window_has_impl (private) && + /* Not for offscreens */ + private->window_type != GDK_WINDOW_OFFSCREEN && + /* or for toplevels */ + !gdk_window_is_toplevel (private) && + /* or for foreign windows */ + private->window_type != GDK_WINDOW_FOREIGN && + /* or for the root window */ + private->window_type != GDK_WINDOW_ROOT; +} + +static void +apply_shape (GdkWindowObject *private, + GdkRegion *region) +{ + GdkWindowImplIface *impl_iface; + + /* We trash whether we applied a shape so that + we can avoid unsetting it many times, which + could happen in e.g. apply_clip_as_shape as + windows get resized */ + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + if (region) + impl_iface->shape_combine_region ((GdkWindow *)private, + region, 0, 0); + else if (private->applied_shape) + impl_iface->shape_combine_region ((GdkWindow *)private, + NULL, 0, 0); + + private->applied_shape = region != NULL; +} + +static void +apply_clip_as_shape (GdkWindowObject *private) +{ + GdkRectangle r; + + r.x = r.y = 0; + r.width = private->width; + r.height = private->height; + + /* We only apply the clip region if would differ + from the actual clip region implied by the size + of the window. This is to avoid unneccessarily + adding meaningless shapes to all native subwindows */ + if (!gdk_region_rect_equal (private->clip_region, &r)) + apply_shape (private, private->clip_region); + else + apply_shape (private, NULL); +} + +static void +recompute_visible_regions_internal (GdkWindowObject *private, + gboolean recalculate_clip, + gboolean recalculate_siblings, + gboolean recalculate_children) +{ + GdkRectangle r; + GList *l; + GdkWindowObject *child; + GdkRegion *new_clip, *old_clip_region_with_children; + gboolean clip_region_changed; + gboolean abs_pos_changed; + int old_abs_x, old_abs_y; + + old_abs_x = private->abs_x; + old_abs_y = private->abs_y; + + /* Update absolute position */ + if (gdk_window_has_impl (private)) + { + /* Native window starts here */ + private->abs_x = 0; + private->abs_y = 0; + } + else + { + private->abs_x = private->parent->abs_x + private->x; + private->abs_y = private->parent->abs_y + private->y; + } + + abs_pos_changed = + private->abs_x != old_abs_x || + private->abs_y != old_abs_y; + + /* Update clip region based on: + * parent clip + * window size + * siblings in parents above window + */ + clip_region_changed = FALSE; + if (recalculate_clip) + { + if (private->viewable) + { + /* Calculate visible region (sans children) in parent window coords */ + r.x = private->x; + r.y = private->y; + r.width = private->width; + r.height = private->height; + new_clip = gdk_region_rectangle (&r); + + if (!gdk_window_is_toplevel (private)) + { + gdk_region_intersect (new_clip, private->parent->clip_region); + + /* Remove all overlapping children from parent. + * Unless we're all native, because then we don't need to take + * siblings into account since X does that clipping for us. + * This makes things like SWT that modify the raw X stacking + * order without GDKs knowledge work. + */ + if (!_gdk_native_windows) + remove_child_area (private->parent, private, FALSE, new_clip); + } + + /* Convert from parent coords to window coords */ + gdk_region_offset (new_clip, -private->x, -private->y); + + if (private->shape) + gdk_region_intersect (new_clip, private->shape); + } + else + new_clip = gdk_region_new (); + + if (private->clip_region == NULL || + !gdk_region_equal (private->clip_region, new_clip)) + clip_region_changed = TRUE; + + if (private->clip_region) + gdk_region_destroy (private->clip_region); + private->clip_region = new_clip; + + old_clip_region_with_children = private->clip_region_with_children; + private->clip_region_with_children = gdk_region_copy (private->clip_region); + if (private->window_type != GDK_WINDOW_ROOT) + remove_child_area (private, NULL, FALSE, private->clip_region_with_children); + + if (clip_region_changed || + !gdk_region_equal (private->clip_region_with_children, old_clip_region_with_children)) + private->clip_tag = new_region_tag (); + + if (old_clip_region_with_children) + gdk_region_destroy (old_clip_region_with_children); + } + + if (clip_region_changed) + { + GdkVisibilityState visibility; + gboolean fully_visible; + + if (gdk_region_empty (private->clip_region)) + visibility = GDK_VISIBILITY_FULLY_OBSCURED; + else + { + if (private->shape) + { + fully_visible = gdk_region_equal (private->clip_region, + private->shape); + } + else + { + r.x = 0; + r.y = 0; + r.width = private->width; + r.height = private->height; + fully_visible = gdk_region_rect_equal (private->clip_region, &r); + } + + if (fully_visible) + visibility = GDK_VISIBILITY_UNOBSCURED; + else + visibility = GDK_VISIBILITY_PARTIAL; + } + + if (private->visibility != visibility) + { + private->visibility = visibility; + gdk_window_update_visibility (private); + } + } + + /* Update all children, recursively (except for root, where children are not exact). */ + if ((abs_pos_changed || clip_region_changed || recalculate_children) && + private->window_type != GDK_WINDOW_ROOT) + { + for (l = private->children; l; l = l->next) + { + child = l->data; + /* Only recalculate clip if the the clip region changed, otherwise + * there is no way the child clip region could change (its has not e.g. moved) + * Except if recalculate_children is set to force child updates + */ + recompute_visible_regions_internal (child, + recalculate_clip && (clip_region_changed || recalculate_children), + FALSE, FALSE); + } + } + + if (clip_region_changed && + should_apply_clip_as_shape (private)) + apply_clip_as_shape (private); + + if (recalculate_siblings && + !gdk_window_is_toplevel (private)) + { + /* If we moved a child window in parent or changed the stacking order, then we + * need to recompute the visible area of all the other children in the parent + */ + for (l = private->parent->children; l; l = l->next) + { + child = l->data; + + if (child != private) + recompute_visible_regions_internal (child, TRUE, FALSE, FALSE); + } + + /* We also need to recompute the _with_children clip for the parent */ + recompute_visible_regions_internal (private->parent, TRUE, FALSE, FALSE); + } + + if (private->cairo_surface) + { + int width, height; + + /* It would be nice if we had some cairo support here so we + could set the clip rect on the cairo surface */ + width = private->abs_x + private->width; + height = private->abs_y + private->height; + + _gdk_windowing_set_cairo_surface_size (private->cairo_surface, + width, height); + cairo_surface_set_device_offset (private->cairo_surface, + private->abs_x, + private->abs_y); + } +} + +/* Call this when private has changed in one or more of these ways: + * size changed + * window moved + * new window added + * stacking order of window changed + * child deleted + * + * It will recalculate abs_x/y and the clip regions + * + * Unless the window didn't change stacking order or size/pos, pass in TRUE + * for recalculate_siblings. (Mostly used internally for the recursion) + * + * If a child window was removed (and you can't use that child for + * recompute_visible_regions), pass in TRUE for recalculate_children on the parent + */ +static void +recompute_visible_regions (GdkWindowObject *private, + gboolean recalculate_siblings, + gboolean recalculate_children) +{ + recompute_visible_regions_internal (private, + TRUE, + recalculate_siblings, + recalculate_children); +} + +void +_gdk_window_update_size (GdkWindow *window) +{ + recompute_visible_regions ((GdkWindowObject *)window, TRUE, FALSE); +} + +/* Find the native window that would be just above "child" + * in the native stacking order if "child" was a native window + * (it doesn't have to be native). If there is no such native + * window inside this native parent then NULL is returned. + * If child is NULL, find lowest native window in parent. + */ +static GdkWindowObject * +find_native_sibling_above_helper (GdkWindowObject *parent, + GdkWindowObject *child) +{ + GdkWindowObject *w; + GList *l; + + if (child) + { + l = g_list_find (parent->children, child); + g_assert (l != NULL); /* Better be a child of its parent... */ + l = l->prev; /* Start looking at the one above the child */ + } + else + l = g_list_last (parent->children); + + for (; l != NULL; l = l->prev) + { + w = l->data; + + if (gdk_window_has_impl (w)) + return w; + + g_assert (parent != w); + w = find_native_sibling_above_helper (w, NULL); + if (w) + return w; + } + + return NULL; +} + + +static GdkWindowObject * +find_native_sibling_above (GdkWindowObject *parent, + GdkWindowObject *child) +{ + GdkWindowObject *w; + + w = find_native_sibling_above_helper (parent, child); + if (w) + return w; + + if (gdk_window_has_impl (parent)) + return NULL; + else + return find_native_sibling_above (parent->parent, parent); +} + +static GdkEventMask +get_native_event_mask (GdkWindowObject *private) +{ + if (_gdk_native_windows || + private->window_type == GDK_WINDOW_ROOT || + private->window_type == GDK_WINDOW_FOREIGN) + return private->event_mask; + else + { + GdkEventMask mask; + + /* Do whatever the app asks to, since the app + * may be asking for weird things for native windows, + * but filter out things that override the special + * requests below. */ + mask = private->event_mask & + ~(GDK_POINTER_MOTION_HINT_MASK | + GDK_BUTTON_MOTION_MASK | + GDK_BUTTON1_MOTION_MASK | + GDK_BUTTON2_MOTION_MASK | + GDK_BUTTON3_MOTION_MASK); + + /* We need thse for all native windows so we can + emulate events on children: */ + mask |= + GDK_EXPOSURE_MASK | + GDK_VISIBILITY_NOTIFY_MASK | + GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK; + + /* Additionally we select for pointer and button events + * for toplevels as we need to get these to emulate + * them for non-native subwindows. Even though we don't + * select on them for all native windows we will get them + * as the events are propagated out to the first window + * that select for them. + * Not selecting for button press on all windows is an + * important thing, because in X only one client can do + * so, and we don't want to unexpectedly prevent another + * client from doing it. + */ + if (gdk_window_is_toplevel (private)) + mask |= + GDK_POINTER_MOTION_MASK | + GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | + GDK_SCROLL_MASK; + + return mask; + } +} + +static GdkEventMask +get_native_grab_event_mask (GdkEventMask grab_mask) +{ + /* Similar to the above but for pointer events only */ + return + GDK_POINTER_MOTION_MASK | + GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | + GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | + GDK_SCROLL_MASK | + (grab_mask & + ~(GDK_POINTER_MOTION_HINT_MASK | + GDK_BUTTON_MOTION_MASK | + GDK_BUTTON1_MOTION_MASK | + GDK_BUTTON2_MOTION_MASK | + GDK_BUTTON3_MOTION_MASK)); +} + +/* Puts the native window in the right order wrt the other native windows + * in the hierarchy, given the position it has in the client side data. + * This is useful if some operation changed the stacking order. + * This calls assumes the native window is now topmost in its native parent. + */ +static void +sync_native_window_stack_position (GdkWindow *window) +{ + GdkWindowObject *above; + GdkWindowObject *private; + GdkWindowImplIface *impl_iface; + GList listhead = {0}; + + private = (GdkWindowObject *) window; + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + + above = find_native_sibling_above (private->parent, private); + if (above) + { + listhead.data = window; + impl_iface->restack_under ((GdkWindow *)above, + &listhead); + } +} + /** * gdk_window_new: * @parent: a #GdkWindow, or %NULL to create the window as a child of * the default root window for the default display. * @attributes: attributes of the new window * @attributes_mask: mask indicating which fields in @attributes are valid - * + * * Creates a new #GdkWindow using the attributes from * @attributes. See #GdkWindowAttr and #GdkWindowAttributesType for * more details. Note: to use this on displays other than the default * display, @parent must be specified. - * + * * Return value: the new #GdkWindow **/ GdkWindow* @@ -371,25 +1266,270 @@ gdk_window_new (GdkWindow *parent, gint attributes_mask) { GdkWindow *window; - GdkWindowObject *private, *parent_private; + GdkWindowObject *private; + GdkScreen *screen; + GdkVisual *visual; + int x, y; + gboolean native; + GdkEventMask event_mask; + GdkWindow *real_parent; - g_return_val_if_fail (parent == NULL || GDK_IS_WINDOW (parent), NULL); g_return_val_if_fail (attributes != NULL, NULL); - window = _gdk_window_new (parent, attributes, attributes_mask); - g_return_val_if_fail (window != NULL, window); - - /* Inherit redirection from parent */ - if (parent != NULL) + if (!parent) { - parent_private = GDK_WINDOW_OBJECT (parent); - private = GDK_WINDOW_OBJECT (window); - private->redirect = parent_private->redirect; + GDK_NOTE (MULTIHEAD, + g_warning ("gdk_window_new(): no parent specified reverting to parent = default root window")); + + screen = gdk_screen_get_default (); + parent = gdk_screen_get_root_window (screen); } - + else + screen = gdk_drawable_get_screen (parent); + + g_return_val_if_fail (GDK_IS_WINDOW (parent), NULL); + + if (GDK_WINDOW_DESTROYED (parent)) + { + g_warning ("gdk_window_new(): parent is destroyed\n"); + return NULL; + } + + if (attributes->window_type == GDK_WINDOW_OFFSCREEN && + _gdk_native_windows) + { + g_warning ("Offscreen windows not supported with native-windows gdk"); + return NULL; + } + + window = g_object_new (GDK_TYPE_WINDOW, NULL); + private = (GdkWindowObject *) window; + + /* Windows with a foreign parent are treated as if they are children + * of the root window, except for actual creation. + */ + real_parent = parent; + if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_FOREIGN) + parent = gdk_screen_get_root_window (screen); + + private->parent = (GdkWindowObject *)parent; + + private->accept_focus = TRUE; + private->focus_on_map = TRUE; + + if (attributes_mask & GDK_WA_X) + x = attributes->x; + else + x = 0; + + if (attributes_mask & GDK_WA_Y) + y = attributes->y; + else + y = 0; + + private->x = x; + private->y = y; + private->width = (attributes->width > 1) ? (attributes->width) : (1); + private->height = (attributes->height > 1) ? (attributes->height) : (1); + +#ifdef GDK_WINDOWING_X11 + /* Work around a bug where Xorg refuses to map toplevel InputOnly windows + * from an untrusted client: http://bugs.freedesktop.org/show_bug.cgi?id=6988 + */ + if (attributes->wclass == GDK_INPUT_ONLY && + private->parent->window_type == GDK_WINDOW_ROOT && + !G_LIKELY (GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (parent))->trusted_client)) + { + g_warning ("Coercing GDK_INPUT_ONLY toplevel window to GDK_INPUT_OUTPUT to work around bug in Xorg server"); + attributes->wclass = GDK_INPUT_OUTPUT; + } +#endif + + if (attributes->wclass == GDK_INPUT_ONLY) + { + /* Backwards compatiblity - we've always ignored + * attributes->window_type for input-only windows + * before + */ + if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_ROOT) + private->window_type = GDK_WINDOW_TEMP; + else + private->window_type = GDK_WINDOW_CHILD; + } + else + private->window_type = attributes->window_type; + + /* Sanity checks */ + switch (private->window_type) + { + case GDK_WINDOW_TOPLEVEL: + case GDK_WINDOW_DIALOG: + case GDK_WINDOW_TEMP: + case GDK_WINDOW_OFFSCREEN: + if (GDK_WINDOW_TYPE (parent) != GDK_WINDOW_ROOT) + g_warning (G_STRLOC "Toplevel windows must be created as children of\n" + "of a window of type GDK_WINDOW_ROOT or GDK_WINDOW_FOREIGN"); + case GDK_WINDOW_CHILD: + break; + break; + default: + g_warning (G_STRLOC "cannot make windows of type %d", private->window_type); + return NULL; + } + + if (attributes_mask & GDK_WA_VISUAL) + visual = attributes->visual; + else + visual = gdk_screen_get_system_visual (screen); + + private->event_mask = attributes->event_mask; + + if (attributes->wclass == GDK_INPUT_OUTPUT) + { + private->input_only = FALSE; + private->depth = visual->depth; + + private->bg_color.pixel = 0; /* TODO: BlackPixel (xdisplay, screen_x11->screen_num); */ + private->bg_color.red = private->bg_color.green = private->bg_color.blue = 0; + + private->bg_pixmap = NULL; + } + else + { + private->depth = 0; + private->input_only = TRUE; + } + + if (private->parent) + private->parent->children = g_list_prepend (private->parent->children, window); + + native = _gdk_native_windows; /* Default */ + if (private->parent->window_type == GDK_WINDOW_ROOT) + native = TRUE; /* Always use native windows for toplevels */ + else if (!private->input_only && + ((attributes_mask & GDK_WA_COLORMAP && + attributes->colormap != gdk_drawable_get_colormap ((GdkDrawable *)private->parent)) || + (attributes_mask & GDK_WA_VISUAL && + attributes->visual != gdk_drawable_get_visual ((GdkDrawable *)private->parent)))) + native = TRUE; /* InputOutput window with different colormap or visual than parent, needs native window */ + + if (private->window_type == GDK_WINDOW_OFFSCREEN) + { + _gdk_offscreen_window_new (window, screen, visual, attributes, attributes_mask); + private->impl_window = private; + } + else if (native) + { + event_mask = get_native_event_mask (private); + + /* Create the impl */ + _gdk_window_impl_new (window, real_parent, screen, visual, event_mask, attributes, attributes_mask); + private->impl_window = private; + + /* This will put the native window topmost in the native parent, which may + * be wrong wrt other native windows in the non-native hierarchy, so restack */ + if (!_gdk_window_has_impl (real_parent)) + sync_native_window_stack_position (window); + } + else + { + private->impl_window = g_object_ref (private->parent->impl_window); + private->impl = g_object_ref (private->impl_window->impl); + } + + recompute_visible_regions (private, TRUE, FALSE); + + if (private->parent->window_type != GDK_WINDOW_ROOT) + { + /* Inherit redirection from parent */ + private->redirect = private->parent->redirect; + } + + gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ? + (attributes->cursor) : + NULL)); + return window; } +static gboolean +is_parent_of (GdkWindow *parent, + GdkWindow *child) +{ + GdkWindow *w; + + w = child; + while (w != NULL) + { + if (w == parent) + return TRUE; + + w = gdk_window_get_parent (w); + } + + return FALSE; +} + +static void +change_impl (GdkWindowObject *private, + GdkWindowObject *impl_window, + GdkDrawable *new) +{ + GList *l; + GdkWindowObject *child; + GdkDrawable *old_impl; + GdkWindowObject *old_impl_window; + + old_impl = private->impl; + old_impl_window = private->impl_window; + if (private != impl_window) + private->impl_window = g_object_ref (impl_window); + else + private->impl_window = private; + private->impl = g_object_ref (new); + if (old_impl_window != private) + g_object_unref (old_impl_window); + g_object_unref (old_impl); + + for (l = private->children; l != NULL; l = l->next) + { + child = l->data; + + if (child->impl == old_impl) + change_impl (child, impl_window, new); + } +} + +static void +reparent_to_impl (GdkWindowObject *private) +{ + GList *l; + GdkWindowObject *child; + gboolean show; + GdkWindowImplIface *impl_iface; + + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + + /* Enumerate in reverse order so we get the right order for the native + windows (first in childrens list is topmost, and reparent places on top) */ + for (l = g_list_last (private->children); l != NULL; l = l->prev) + { + child = l->data; + + if (child->impl == private->impl) + reparent_to_impl (child); + else + { + show = impl_iface->reparent ((GdkWindow *)child, + (GdkWindow *)private, + child->x, child->y); + if (show) + gdk_window_show_unraised ((GdkWindow *)child); + } + } +} + + /** * gdk_window_reparent: * @window: a #GdkWindow @@ -399,7 +1539,7 @@ gdk_window_new (GdkWindow *parent, * * Reparents @window into the given @new_parent. The window being * reparented will be unmapped as a side effect. - * + * **/ void gdk_window_reparent (GdkWindow *window, @@ -408,7 +1548,13 @@ gdk_window_reparent (GdkWindow *window, gint y) { GdkWindowObject *private; - gboolean show; + GdkWindowObject *new_parent_private; + GdkWindowObject *old_parent; + GdkScreen *screen; + gboolean show, was_mapped, applied_clip_as_shape; + gboolean do_reparent_to_impl; + GdkEventMask old_native_event_mask; + GdkWindowImplIface *impl_iface; g_return_if_fail (GDK_IS_WINDOW (window)); g_return_if_fail (new_parent == NULL || GDK_IS_WINDOW (new_parent)); @@ -416,11 +1562,34 @@ gdk_window_reparent (GdkWindow *window, if (GDK_WINDOW_DESTROYED (window) || (new_parent && GDK_WINDOW_DESTROYED (new_parent))) - { - return; - } + return; + + screen = gdk_drawable_get_screen (GDK_DRAWABLE (window)); + if (!new_parent) + new_parent = gdk_screen_get_root_window (screen); private = (GdkWindowObject *) window; + new_parent_private = (GdkWindowObject *)new_parent; + + /* No input-output children of input-only windows */ + if (new_parent_private->input_only && !private->input_only) + return; + + /* Don't create loops in hierarchy */ + if (is_parent_of (window, new_parent)) + return; + + if (private->cairo_surface) + { + /* This might be wrong in the new parent, e.g. for non-native surfaces. + To make sure we're ok, just wipe it. */ + cairo_surface_finish (private->cairo_surface); + cairo_surface_set_user_data (private->cairo_surface, &gdk_window_cairo_key, + NULL, NULL); + } + + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + old_parent = private->parent; /* Break up redirection if inherited */ if (private->redirect && private->redirect->redirected != private) @@ -428,8 +1597,94 @@ gdk_window_reparent (GdkWindow *window, remove_redirect_from_children (private, private->redirect); private->redirect = NULL; } - - show = GDK_WINDOW_IMPL_GET_IFACE (private->impl)->reparent (window, new_parent, x, y); + + was_mapped = GDK_WINDOW_IS_MAPPED (window); + show = FALSE; + + /* Reparenting to toplevel. Ensure we have a native window so this can work */ + if (new_parent_private->window_type == GDK_WINDOW_ROOT || + new_parent_private->window_type == GDK_WINDOW_FOREIGN) + gdk_window_ensure_native (window); + + applied_clip_as_shape = should_apply_clip_as_shape (private); + + old_native_event_mask = 0; + do_reparent_to_impl = FALSE; + if (gdk_window_has_impl (private)) + { + old_native_event_mask = get_native_event_mask (private); + /* Native window */ + show = impl_iface->reparent (window, new_parent, x, y); + } + else + { + /* This shouldn't happen, as we created a native in this case, check anyway to see if that ever fails */ + g_assert (new_parent_private->window_type != GDK_WINDOW_ROOT && + new_parent_private->window_type != GDK_WINDOW_FOREIGN); + + show = was_mapped; + gdk_window_hide (window); + + do_reparent_to_impl = TRUE; + change_impl (private, + new_parent_private->impl_window, + new_parent_private->impl); + } + + /* From here on, we treat parents of type GDK_WINDOW_FOREIGN like + * the root window + */ + if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN) + { + new_parent = gdk_screen_get_root_window (screen); + new_parent_private = (GdkWindowObject *)new_parent; + } + + if (old_parent) + old_parent->children = g_list_remove (old_parent->children, window); + + private->parent = new_parent_private; + private->x = x; + private->y = y; + + new_parent_private->children = g_list_prepend (new_parent_private->children, window); + + /* Switch the window type as appropriate */ + + switch (GDK_WINDOW_TYPE (new_parent)) + { + case GDK_WINDOW_ROOT: + case GDK_WINDOW_FOREIGN: + if (private->toplevel_window_type != -1) + GDK_WINDOW_TYPE (window) = private->toplevel_window_type; + else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD) + GDK_WINDOW_TYPE (window) = GDK_WINDOW_TOPLEVEL; + break; + case GDK_WINDOW_OFFSCREEN: + case GDK_WINDOW_TOPLEVEL: + case GDK_WINDOW_CHILD: + case GDK_WINDOW_DIALOG: + case GDK_WINDOW_TEMP: + if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \ + GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN) + { + /* Save the original window type so we can restore it if the + * window is reparented back to be a toplevel + */ + private->toplevel_window_type = GDK_WINDOW_TYPE (window); + GDK_WINDOW_TYPE (window) = GDK_WINDOW_CHILD; + } + } + + /* We might have changed window type for a native windows, so we + need to change the event mask too. */ + if (gdk_window_has_impl (private)) + { + GdkEventMask native_event_mask = get_native_event_mask (private); + + if (native_event_mask != old_native_event_mask) + impl_iface->set_events (window, native_event_mask); + } /* Inherit parent redirect if we don't have our own */ if (private->parent && private->redirect == NULL) @@ -438,8 +1693,137 @@ gdk_window_reparent (GdkWindow *window, apply_redirect_to_children (private, private->redirect); } + _gdk_window_update_viewable (window); + + recompute_visible_regions (private, TRUE, FALSE); + if (old_parent && GDK_WINDOW_TYPE (old_parent) != GDK_WINDOW_ROOT) + recompute_visible_regions (old_parent, FALSE, TRUE); + + /* We used to apply the clip as the shape, but no more. + Reset this to the real shape */ + if (gdk_window_has_impl (private) && + applied_clip_as_shape && + !should_apply_clip_as_shape (private)) + apply_shape (private, private->shape); + + if (do_reparent_to_impl) + reparent_to_impl (private); + else + { + /* The reparent will have put the native window topmost in the native parent, + * which may be wrong wrt other native windows in the non-native hierarchy, + * so restack */ + if (!gdk_window_has_impl (new_parent_private)) + sync_native_window_stack_position (window); + } + if (show) - gdk_window_show (window); + gdk_window_show_unraised (window); + else + _gdk_synthesize_crossing_events_for_geometry_change (window); +} + +/** + * gdk_window_ensure_native: + * @window: a #GdkWindow + * + * Tries to ensure that there is a window-system native window for this + * GdkWindow. This may fail in some situations, returning %FALSE. + * + * Offscreen window and children of them can never have native windows. + * + * Some backends may not support native child windows. + * + * Returns: %TRUE if the window has a native window, %FALSE otherwise + * + * Since: 2.18 + */ +gboolean +gdk_window_ensure_native (GdkWindow *window) +{ + GdkWindowObject *private; + GdkWindowObject *impl_window; + GdkDrawable *new_impl, *old_impl; + GdkScreen *screen; + GdkVisual *visual; + GdkWindowAttr attributes; + GdkWindowObject *above; + GList listhead; + GdkWindowImplIface *impl_iface; + + g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE); + + if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_ROOT || + GDK_WINDOW_DESTROYED (window)) + return FALSE; + + private = (GdkWindowObject *) window; + + impl_window = gdk_window_get_impl_window (private); + + if (impl_window->window_type == GDK_WINDOW_OFFSCREEN) + return FALSE; /* native in offscreens not supported */ + + if (impl_window == private) + /* Already has an impl, and its not offscreen . */ + return TRUE; + + /* Need to create a native window */ + + screen = gdk_drawable_get_screen (window); + visual = gdk_drawable_get_visual (window); + + attributes.colormap = gdk_drawable_get_colormap (window); + + old_impl = private->impl; + _gdk_window_impl_new (window, (GdkWindow *)private->parent, + screen, visual, + get_native_event_mask (private), + &attributes, GDK_WA_COLORMAP); + new_impl = private->impl; + + private->impl = old_impl; + change_impl (private, private, new_impl); + + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + + /* Native window creation will put the native window topmost in the + * native parent, which may be wrong wrt the position of the previous + * non-native window wrt to the other non-native children, so correct this. + */ + above = find_native_sibling_above (private->parent, private); + if (above) + { + listhead.data = window; + listhead.prev = NULL; + listhead.next = NULL; + impl_iface->restack_under ((GdkWindow *)above, &listhead); + } + + recompute_visible_regions (private, FALSE, FALSE); + + /* The shape may not have been set, as the clip region doesn't actually + change, so do it here manually */ + if (should_apply_clip_as_shape (private)) + apply_clip_as_shape (private); + + reparent_to_impl (private); + + if (!private->input_only) + { + impl_iface->set_background (window, &private->bg_color); + if (private->bg_pixmap != NULL) + impl_iface->set_back_pixmap (window, private->bg_pixmap); + } + + impl_iface->input_shape_combine_region (window, + private->input_shape, + 0, 0); + + if (gdk_window_is_viewable (window)) + impl_iface->show (window, FALSE); + + return TRUE; } static void @@ -450,10 +1834,10 @@ window_remove_filters (GdkWindow *window) if (obj->filters) { GList *tmp_list; - + for (tmp_list = obj->filters; tmp_list; tmp_list = tmp_list->next) g_free (tmp_list->data); - + g_list_free (obj->filters); obj->filters = NULL; } @@ -463,12 +1847,14 @@ window_remove_filters (GdkWindow *window) * _gdk_window_destroy_hierarchy: * @window: a #GdkWindow * @recursing: If TRUE, then this is being called because a parent - * was destroyed. This generally means that the call to the + * was destroyed. + * @recursing_native: If TRUE, then this is being called because a native parent + * was destroyed. This generally means that the call to the * windowing system to destroy the window can be omitted, since * it will be destroyed as a result of the parent being destroyed. - * Unless @foreign_destroy. - * @foreign_destroy: If TRUE, the window or a parent was destroyed by some - * external agency. The window has already been destroyed and no + * Unless @foreign_destroy. + * @foreign_destroy: If TRUE, the window or a parent was destroyed by some + * external agency. The window has already been destroyed and no * windowing system calls should be made. (This may never happen * for some windowing systems.) * @@ -478,28 +1864,33 @@ window_remove_filters (GdkWindow *window) static void _gdk_window_destroy_hierarchy (GdkWindow *window, gboolean recursing, + gboolean recursing_native, gboolean foreign_destroy) { GdkWindowObject *private; GdkWindowObject *temp_private; + GdkWindowImplIface *impl_iface; GdkWindow *temp_window; GdkScreen *screen; + GdkDisplay *display; GList *children; GList *tmp; g_return_if_fail (GDK_IS_WINDOW (window)); private = (GdkWindowObject*) window; - + if (GDK_WINDOW_DESTROYED (window)) return; - + + display = gdk_drawable_get_display (GDK_DRAWABLE (window)); screen = gdk_drawable_get_screen (GDK_DRAWABLE (window)); temp_window = g_object_get_qdata (G_OBJECT (screen), quark_pointer_window); if (temp_window == window) g_object_set_qdata (G_OBJECT (screen), quark_pointer_window, NULL); - switch (GDK_WINDOW_TYPE (window)) + + switch (private->window_type) { case GDK_WINDOW_ROOT: if (!screen->closed) @@ -513,7 +1904,8 @@ _gdk_window_destroy_hierarchy (GdkWindow *window, case GDK_WINDOW_DIALOG: case GDK_WINDOW_TEMP: case GDK_WINDOW_FOREIGN: - if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_FOREIGN && !foreign_destroy) + case GDK_WINDOW_OFFSCREEN: + if (private->window_type == GDK_WINDOW_FOREIGN && !foreign_destroy) { /* Logically, it probably makes more sense to send * a "destroy yourself" message to the foreign window @@ -533,60 +1925,116 @@ _gdk_window_destroy_hierarchy (GdkWindow *window, } else { - private->state |= GDK_WINDOW_STATE_WITHDRAWN; - if (private->parent) { GdkWindowObject *parent_private = (GdkWindowObject *)private->parent; + if (parent_private->children) parent_private->children = g_list_remove (parent_private->children, window); + + if (!recursing && + GDK_WINDOW_IS_MAPPED (window)) + { + recompute_visible_regions (private, TRUE, FALSE); + gdk_window_invalidate_in_parent (private); + } } - _gdk_window_clear_update_area (window); gdk_window_free_paint_stack (window); - + if (private->bg_pixmap && - private->bg_pixmap != GDK_PARENT_RELATIVE_BG && - private->bg_pixmap != GDK_NO_BG) + private->bg_pixmap != GDK_PARENT_RELATIVE_BG && + private->bg_pixmap != GDK_NO_BG) { g_object_unref (private->bg_pixmap); private->bg_pixmap = NULL; } - - if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_FOREIGN) + + if (private->window_type == GDK_WINDOW_FOREIGN) g_assert (private->children == NULL); else { children = tmp = private->children; private->children = NULL; - + while (tmp) { temp_window = tmp->data; tmp = tmp->next; - + temp_private = (GdkWindowObject*) temp_window; if (temp_private) _gdk_window_destroy_hierarchy (temp_window, - TRUE, foreign_destroy); + TRUE, + recursing_native || gdk_window_has_impl (private), + foreign_destroy); } - + g_list_free (children); } - - _gdk_windowing_window_destroy (window, recursing, foreign_destroy); + + _gdk_window_clear_update_area (window); + + if (private->cairo_surface) + { + cairo_surface_finish (private->cairo_surface); + cairo_surface_set_user_data (private->cairo_surface, &gdk_window_cairo_key, + NULL, NULL); + } + + + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + + if (private->extension_events) + impl_iface->input_window_destroy (window); + + if (gdk_window_has_impl (private)) + impl_iface->destroy (window, recursing_native, + foreign_destroy); + else + { + /* hide to make sure we repaint and break grabs */ + gdk_window_hide (window); + } + + private->state |= GDK_WINDOW_STATE_WITHDRAWN; private->parent = NULL; private->destroyed = TRUE; window_remove_filters (window); - gdk_drawable_set_colormap (GDK_DRAWABLE (window), NULL); + gdk_drawable_set_colormap (GDK_DRAWABLE (window), NULL); /* If we own the redirect, free it */ if (private->redirect && private->redirect->redirected == private) gdk_window_redirect_free (private->redirect); private->redirect = NULL; + + if (display->pointer_info.toplevel_under_pointer == window) + { + g_object_unref (display->pointer_info.toplevel_under_pointer); + display->pointer_info.toplevel_under_pointer = NULL; + } + + if (private->clip_region) + { + gdk_region_destroy (private->clip_region); + private->clip_region = NULL; + } + + if (private->clip_region_with_children) + { + gdk_region_destroy (private->clip_region_with_children); + private->clip_region_with_children = NULL; + } + + if (private->outstanding_moves) + { + g_list_foreach (private->outstanding_moves, (GFunc)gdk_window_region_move_free, NULL); + g_list_free (private->outstanding_moves); + private->outstanding_moves = NULL; + } } break; } @@ -607,7 +2055,7 @@ void _gdk_window_destroy (GdkWindow *window, gboolean foreign_destroy) { - _gdk_window_destroy_hierarchy (window, FALSE, foreign_destroy); + _gdk_window_destroy_hierarchy (window, FALSE, FALSE, foreign_destroy); } /** @@ -625,7 +2073,7 @@ _gdk_window_destroy (GdkWindow *window, void gdk_window_destroy (GdkWindow *window) { - _gdk_window_destroy_hierarchy (window, FALSE, FALSE); + _gdk_window_destroy_hierarchy (window, FALSE, FALSE, FALSE); g_object_unref (window); } @@ -641,7 +2089,7 @@ gdk_window_destroy (GdkWindow *window) * this function for that. If GTK+ receives an event for a #GdkWindow, * and the user data for the window is non-%NULL, GTK+ will assume the * user data is a #GtkWidget, and forward the event to that widget. - * + * **/ void gdk_window_set_user_data (GdkWindow *window, @@ -659,7 +2107,7 @@ gdk_window_set_user_data (GdkWindow *window, * * Retrieves the user data for @window, which is normally the widget * that @window belongs to. See gdk_window_set_user_data(). - * + * **/ void gdk_window_get_user_data (GdkWindow *window, @@ -673,19 +2121,33 @@ gdk_window_get_user_data (GdkWindow *window, /** * gdk_window_get_window_type: * @window: a #GdkWindow - * + * * Gets the type of the window. See #GdkWindowType. - * + * * Return value: type of window **/ GdkWindowType gdk_window_get_window_type (GdkWindow *window) { g_return_val_if_fail (GDK_IS_WINDOW (window), (GdkWindowType) -1); - + return GDK_WINDOW_TYPE (window); } +/** + * gdk_window_is_destroyed: + * @window: a #GdkWindow + * + * Check to see if a window is destroyed.. + * + * Return value: %TRUE if the window is destroyed + **/ +gboolean +gdk_window_is_destroyed (GdkWindow *window) +{ + return GDK_WINDOW_DESTROYED (window); +} + /** * gdk_window_get_position: * @window: a #GdkWindow @@ -699,7 +2161,7 @@ gdk_window_get_window_type (GdkWindow *window) * received or processed. * * The position coordinates are relative to the window's parent window. - * + * **/ void gdk_window_get_position (GdkWindow *window, @@ -707,11 +2169,11 @@ gdk_window_get_position (GdkWindow *window, gint *y) { GdkWindowObject *obj; - + g_return_if_fail (GDK_IS_WINDOW (window)); - + obj = (GdkWindowObject*) window; - + if (x) *x = obj->x; if (y) @@ -721,50 +2183,59 @@ gdk_window_get_position (GdkWindow *window, /** * gdk_window_get_parent: * @window: a #GdkWindow - * + * * Obtains the parent of @window, as known to GDK. Does not query the * X server; thus this returns the parent as passed to gdk_window_new(), * not the actual parent. This should never matter unless you're using * Xlib calls mixed with GDK calls on the X11 platform. It may also * matter for toplevel windows, because the window manager may choose * to reparent them. - * + * * Return value: parent of @window **/ GdkWindow* gdk_window_get_parent (GdkWindow *window) { g_return_val_if_fail (GDK_IS_WINDOW (window), NULL); - + return (GdkWindow*) ((GdkWindowObject*) window)->parent; } /** * gdk_window_get_toplevel: * @window: a #GdkWindow - * + * * Gets the toplevel window that's an ancestor of @window. - * + * + * Any window type but %GDK_WINDOW_CHILD is considered a + * toplevel window, as is a %GDK_WINDOW_CHILD window that + * has a root window as parent. + * * Return value: the toplevel window containing @window **/ GdkWindow* gdk_window_get_toplevel (GdkWindow *window) { GdkWindowObject *obj; - + g_return_val_if_fail (GDK_IS_WINDOW (window), NULL); obj = (GdkWindowObject *)window; - while (GDK_WINDOW_TYPE (obj) == GDK_WINDOW_CHILD) - obj = (GdkWindowObject *)obj->parent; - + + while (obj->window_type == GDK_WINDOW_CHILD) + { + if (gdk_window_is_toplevel (obj)) + break; + obj = obj->parent; + } + return GDK_WINDOW (obj); } /** * gdk_window_get_children: * @window: a #GdkWindow - * + * * Gets the list of children of @window known to GDK. * This function only returns children created via GDK, * so for example it's useless when used with the root window; @@ -772,7 +2243,7 @@ gdk_window_get_toplevel (GdkWindow *window) * * The returned list must be freed, but the elements in the * list need not be. - * + * * Return value: list of child windows inside @window **/ GList* @@ -789,10 +2260,10 @@ gdk_window_get_children (GdkWindow *window) /** * gdk_window_peek_children: * @window: a #GdkWindow - * + * * Like gdk_window_get_children(), but does not copy the list of * children, so the list does not need to be freed. - * + * * Return value: a reference to the list of child windows in @window **/ GList * @@ -821,7 +2292,7 @@ gdk_window_peek_children (GdkWindow *window) * See gdk_display_add_client_message_filter() if you are interested * in X ClientMessage events. **/ -void +void gdk_window_add_filter (GdkWindow *window, GdkFilterFunc function, gpointer data) @@ -829,18 +2300,23 @@ gdk_window_add_filter (GdkWindow *window, GdkWindowObject *private; GList *tmp_list; GdkEventFilter *filter; - + g_return_if_fail (window == NULL || GDK_IS_WINDOW (window)); private = (GdkWindowObject*) window; if (private && GDK_WINDOW_DESTROYED (window)) return; - + + /* Filters are for the native events on the native window, so + ensure there is a native window. */ + if (window) + gdk_window_ensure_native (window); + if (private) tmp_list = private->filters; else tmp_list = _gdk_default_filters; - + while (tmp_list) { filter = (GdkEventFilter *)tmp_list->data; @@ -848,11 +2324,11 @@ gdk_window_add_filter (GdkWindow *window, return; tmp_list = tmp_list->next; } - + filter = g_new (GdkEventFilter, 1); filter->function = function; filter->data = data; - + if (private) private->filters = g_list_append (private->filters, filter); else @@ -866,7 +2342,7 @@ gdk_window_add_filter (GdkWindow *window, * @data: user data for previously-added filter function * * Remove a filter previously added with gdk_window_add_filter(). - * + * **/ void gdk_window_remove_filter (GdkWindow *window, @@ -876,22 +2352,22 @@ gdk_window_remove_filter (GdkWindow *window, GdkWindowObject *private; GList *tmp_list, *node; GdkEventFilter *filter; - + g_return_if_fail (window == NULL || GDK_IS_WINDOW (window)); private = (GdkWindowObject*) window; - + if (private) tmp_list = private->filters; else tmp_list = _gdk_default_filters; - + while (tmp_list) { filter = (GdkEventFilter *)tmp_list->data; node = tmp_list; tmp_list = tmp_list->next; - + if ((filter->function == function) && (filter->data == data)) { if (private) @@ -900,7 +2376,7 @@ gdk_window_remove_filter (GdkWindow *window, _gdk_default_filters = g_list_remove_link (_gdk_default_filters, node); g_list_free_1 (node); g_free (filter); - + return; } } @@ -909,14 +2385,14 @@ gdk_window_remove_filter (GdkWindow *window, /** * gdk_screen_get_toplevel_windows: * @screen: The #GdkScreen where the toplevels are located. - * + * * Obtains a list of all toplevel windows known to GDK on the screen @screen. * A toplevel window is a child of the root window (see * gdk_get_default_root_window()). * * The returned list should be freed with g_list_free(), but * its elements need not be freed. - * + * * Return value: list of toplevel windows, free with g_list_free() * * Since: 2.2 @@ -927,25 +2403,27 @@ gdk_screen_get_toplevel_windows (GdkScreen *screen) GdkWindow * root_window; GList *new_list = NULL; GList *tmp_list; - + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); - + root_window = gdk_screen_get_root_window (screen); tmp_list = ((GdkWindowObject *)root_window)->children; while (tmp_list) { - if (GDK_WINDOW_TYPE (tmp_list->data) != GDK_WINDOW_FOREIGN) - new_list = g_list_prepend (new_list, tmp_list->data); + GdkWindowObject *w = tmp_list->data; + + if (w->window_type != GDK_WINDOW_FOREIGN) + new_list = g_list_prepend (new_list, w); tmp_list = tmp_list->next; } - + return new_list; } /** * gdk_window_get_toplevels: - * + * * Obtains a list of all toplevel windows known to GDK on the default * screen (see gdk_screen_get_toplevel_windows()). * A toplevel window is a child of the root window (see @@ -953,11 +2431,11 @@ gdk_screen_get_toplevel_windows (GdkScreen *screen) * * The returned list should be freed with g_list_free(), but * its elements need not be freed. - * + * * Return value: list of toplevel windows, free with g_list_free() * * Deprecated: 2.16: Use gdk_screen_get_toplevel_windows() instead. - **/ + */ GList * gdk_window_get_toplevels (void) { @@ -967,24 +2445,24 @@ gdk_window_get_toplevels (void) /** * gdk_window_is_visible: * @window: a #GdkWindow - * + * * Checks whether the window has been mapped (with gdk_window_show() or * gdk_window_show_unraised()). - * + * * Return value: %TRUE if the window is mapped **/ -gboolean +gboolean gdk_window_is_visible (GdkWindow *window) { g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE); - + return GDK_WINDOW_IS_MAPPED (window); } /** * gdk_window_is_viewable: * @window: a #GdkWindow - * + * * Check if the window and all ancestors of the window are * mapped. (This is not necessarily "viewable" in the X sense, since * we only check as far as we have GDK window parents, not to the root @@ -992,50 +2470,165 @@ gdk_window_is_visible (GdkWindow *window) * * Return value: %TRUE if the window is viewable **/ -gboolean +gboolean gdk_window_is_viewable (GdkWindow *window) { GdkWindowObject *private = (GdkWindowObject *)window; - GdkScreen *screen; - GdkWindow *root_window; g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE); - screen = gdk_drawable_get_screen (window); - root_window = gdk_screen_get_root_window (screen); - - while (private && - (private != (GdkWindowObject *)root_window) && - (GDK_WINDOW_TYPE (private) != GDK_WINDOW_FOREIGN)) - { - if (GDK_WINDOW_DESTROYED (private) || !GDK_WINDOW_IS_MAPPED (private)) - return FALSE; - - private = (GdkWindowObject *)private->parent; - } - - return TRUE; + if (private->destroyed) + return FALSE; + + return private->viewable; } /** * gdk_window_get_state: * @window: a #GdkWindow - * + * * Gets the bitwise OR of the currently active window state flags, * from the #GdkWindowState enumeration. - * + * * Return value: window state bitfield **/ GdkWindowState gdk_window_get_state (GdkWindow *window) { GdkWindowObject *private = (GdkWindowObject *)window; - + g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE); - + return private->state; } + +/* This creates an empty "implicit" paint region for the impl window. + * By itself this does nothing, but real paints to this window + * or children of it can use this pixmap as backing to avoid allocating + * multiple pixmaps for subwindow rendering. When doing so they + * add to the region of the implicit paint region, which will be + * pushed to the window when the implicit paint region is ended. + * Such paints should not copy anything to the window on paint end, but + * should rely on the implicit paint end. + * The implicit paint will be automatically ended if someone draws + * directly to the window or a child window. + */ +static gboolean +gdk_window_begin_implicit_paint (GdkWindow *window, GdkRectangle *rect) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowPaint *paint; + + g_assert (gdk_window_has_impl (private)); + + if (_gdk_native_windows) + return FALSE; /* No need for implicit paints since we can't merge draws anyway */ + + if (GDK_IS_PAINTABLE (private->impl)) + return FALSE; /* Implementation does double buffering */ + + if (private->paint_stack != NULL || + private->implicit_paint != NULL) + return FALSE; /* Don't stack implicit paints */ + + paint = g_new (GdkWindowPaint, 1); + paint->region = gdk_region_new (); /* Empty */ + paint->x_offset = rect->x; + paint->y_offset = rect->y; + paint->uses_implicit = FALSE; + paint->flushed = FALSE; + paint->surface = NULL; + paint->pixmap = + gdk_pixmap_new (window, + MAX (rect->width, 1), MAX (rect->height, 1), -1); + + private->implicit_paint = paint; + + return TRUE; +} + +/* Ensure that all content related to this (sub)window is pushed to the + native region. If there is an active paint then that area is not + pushed, in order to not show partially finished double buffers. */ +static void +gdk_window_flush_implicit_paint (GdkWindow *window) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowObject *impl_window; + GdkWindowPaint *paint; + GdkRegion *region; + GdkGC *tmp_gc; + GSList *list; + + impl_window = gdk_window_get_impl_window (private); + if (impl_window->implicit_paint == NULL) + return; + + paint = impl_window->implicit_paint; + paint->flushed = TRUE; + region = gdk_region_copy (private->clip_region_with_children); + + /* Don't flush active double buffers, as that may show partially done + * rendering */ + for (list = private->paint_stack; list != NULL; list = list->next) + { + GdkWindowPaint *tmp_paint = list->data; + + gdk_region_subtract (region, tmp_paint->region); + } + + gdk_region_offset (region, private->abs_x, private->abs_y); + gdk_region_intersect (region, paint->region); + + if (!gdk_region_empty (region)) + { + /* Remove flushed region from the implicit paint */ + gdk_region_subtract (paint->region, region); + + /* Some regions are valid, push these to window now */ + tmp_gc = _gdk_drawable_get_scratch_gc ((GdkDrawable *)window, FALSE); + _gdk_gc_set_clip_region_internal (tmp_gc, region, TRUE); + gdk_draw_drawable (private->impl, tmp_gc, paint->pixmap, + 0, 0, paint->x_offset, paint->y_offset, -1, -1); + /* Reset clip region of the cached GdkGC */ + gdk_gc_set_clip_region (tmp_gc, NULL); + } + else + gdk_region_destroy (region); +} + +/* Ends an implicit paint, paired with gdk_window_begin_implicit_paint returning TRUE */ +static void +gdk_window_end_implicit_paint (GdkWindow *window) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowPaint *paint; + GdkGC *tmp_gc; + + g_assert (gdk_window_has_impl (private)); + + g_assert (private->implicit_paint != NULL); + + paint = private->implicit_paint; + + private->implicit_paint = NULL; + + if (!gdk_region_empty (paint->region)) + { + /* Some regions are valid, push these to window now */ + tmp_gc = _gdk_drawable_get_scratch_gc ((GdkDrawable *)window, FALSE); + _gdk_gc_set_clip_region_internal (tmp_gc, paint->region, TRUE); + gdk_draw_drawable (private->impl, tmp_gc, paint->pixmap, + 0, 0, paint->x_offset, paint->y_offset, -1, -1); + /* Reset clip region of the cached GdkGC */ + gdk_gc_set_clip_region (tmp_gc, NULL); + } + + g_object_unref (paint->pixmap); + g_free (paint); +} + /** * gdk_window_begin_paint_rect: * @window: a #GdkWindow @@ -1044,11 +2637,11 @@ gdk_window_get_state (GdkWindow *window) * A convenience wrapper around gdk_window_begin_paint_region() which * creates a rectangular region for you. See * gdk_window_begin_paint_region() for details. - * + * **/ void gdk_window_begin_paint_rect (GdkWindow *window, - const GdkRectangle *rectangle) + const GdkRectangle *rectangle) { GdkRegion *region; @@ -1059,10 +2652,6 @@ gdk_window_begin_paint_rect (GdkWindow *window, gdk_region_destroy (region); } -#ifdef GDK_WINDOWING_X11 -#include "x11/gdkx.h" -#endif - /** * gdk_window_begin_paint_region: * @window: a #GdkWindow @@ -1106,16 +2695,17 @@ gdk_window_begin_paint_rect (GdkWindow *window, * the topmost backing store in the stack. One matching call to * gdk_window_end_paint() is required for each call to * gdk_window_begin_paint_region(). - * + * **/ -void +void gdk_window_begin_paint_region (GdkWindow *window, - const GdkRegion *region) + const GdkRegion *region) { #ifdef USE_BACKING_STORE GdkWindowObject *private = (GdkWindowObject *)window; GdkRectangle clip_box; - GdkWindowPaint *paint; + GdkWindowPaint *paint, *implicit_paint; + GdkWindowObject *impl_window; GSList *list; g_return_if_fail (GDK_IS_WINDOW (window)); @@ -1123,48 +2713,131 @@ gdk_window_begin_paint_region (GdkWindow *window, if (GDK_WINDOW_DESTROYED (window)) return; - if (GDK_IS_PAINTABLE (private->impl)) + if (GDK_IS_PAINTABLE (private->impl)) { GdkPaintableIface *iface = GDK_PAINTABLE_GET_IFACE (private->impl); if (iface->begin_paint_region) - iface->begin_paint_region ((GdkPaintable*)private->impl, region); + iface->begin_paint_region ((GdkPaintable*)private->impl, window, region); return; } - gdk_region_get_clipbox (region, &clip_box); + impl_window = gdk_window_get_impl_window (private); + implicit_paint = impl_window->implicit_paint; paint = g_new (GdkWindowPaint, 1); paint->region = gdk_region_copy (region); - paint->x_offset = clip_box.x; - paint->y_offset = clip_box.y; - paint->pixmap = - gdk_pixmap_new (window, - MAX (clip_box.width, 1), MAX (clip_box.height, 1), -1); + paint->region_tag = new_region_tag (); + + gdk_region_intersect (paint->region, private->clip_region_with_children); + gdk_region_get_clipbox (paint->region, &clip_box); + + /* Convert to impl coords */ + gdk_region_offset (paint->region, private->abs_x, private->abs_y); + + /* Mark the region as valid on the implicit paint */ + + if (implicit_paint) + gdk_region_union (implicit_paint->region, paint->region); + + /* Convert back to normal coords */ + gdk_region_offset (paint->region, -private->abs_x, -private->abs_y); + + if (implicit_paint) + { + int width, height; + + paint->uses_implicit = TRUE; + paint->pixmap = g_object_ref (implicit_paint->pixmap); + paint->x_offset = -private->abs_x + implicit_paint->x_offset; + paint->y_offset = -private->abs_y + implicit_paint->y_offset; + + gdk_drawable_get_size (paint->pixmap, &width, &height); + paint->surface = _gdk_drawable_create_cairo_surface (paint->pixmap, width, height); + } + else + { + paint->uses_implicit = FALSE; + paint->x_offset = clip_box.x; + paint->y_offset = clip_box.y; + paint->pixmap = + gdk_pixmap_new (window, + MAX (clip_box.width, 1), MAX (clip_box.height, 1), -1); + paint->surface = _gdk_drawable_ref_cairo_surface (paint->pixmap); + } + + if (paint->surface) + cairo_surface_set_device_offset (paint->surface, + -paint->x_offset, -paint->y_offset); - paint->surface = _gdk_drawable_ref_cairo_surface (paint->pixmap); - cairo_surface_set_device_offset (paint->surface, - - paint->x_offset, - paint->y_offset); - for (list = private->paint_stack; list != NULL; list = list->next) { GdkWindowPaint *tmp_paint = list->data; gdk_region_subtract (tmp_paint->region, paint->region); } - + private->paint_stack = g_slist_prepend (private->paint_stack, paint); - if (!gdk_region_empty (region)) + if (!gdk_region_empty (paint->region)) { - gdk_window_clear_backing_rect (window, - clip_box.x, clip_box.y, - clip_box.width, clip_box.height); + gdk_window_clear_backing_region (window, + paint->region); } + #endif /* USE_BACKING_STORE */ } +static void +setup_redirect_clip (GdkWindow *window, + GdkGC *gc, + int *x_offset_out, + int *y_offset_out) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkRegion *visible_region; + GdkRectangle dest_rect; + GdkRegion *tmpreg; + GdkWindow *toplevel; + int x_offset, y_offset; + + toplevel = GDK_WINDOW (private->redirect->redirected); + + /* Get the clip region for gc clip rect + window hierarchy in + window relative coords */ + visible_region = + _gdk_window_calculate_full_clip_region (window, toplevel, + TRUE, + &x_offset, + &y_offset); + + /* Compensate for the source pos/size */ + x_offset -= private->redirect->src_x; + y_offset -= private->redirect->src_y; + dest_rect.x = -x_offset; + dest_rect.y = -y_offset; + dest_rect.width = private->redirect->width; + dest_rect.height = private->redirect->height; + tmpreg = gdk_region_rectangle (&dest_rect); + gdk_region_intersect (visible_region, tmpreg); + gdk_region_destroy (tmpreg); + + /* Compensate for the dest pos */ + x_offset += private->redirect->dest_x; + y_offset += private->redirect->dest_y; + + gdk_gc_set_clip_region (gc, visible_region); /* This resets clip origin! */ + + /* offset clip and tiles from window coords to pixmaps coords */ + gdk_gc_offset (gc, -x_offset, -y_offset); + + gdk_region_destroy (visible_region); + + *x_offset_out = x_offset; + *y_offset_out = y_offset; +} + /** * gdk_window_end_paint: * @window: a #GdkWindow @@ -1176,7 +2849,7 @@ gdk_window_begin_paint_region (GdkWindow *window, * gdk_window_begin_paint_region() for full details. It is an error to * call this function without a matching * gdk_window_begin_paint_region() first. - * + * **/ void gdk_window_end_paint (GdkWindow *window) @@ -1188,6 +2861,7 @@ gdk_window_end_paint (GdkWindow *window) GdkGC *tmp_gc; GdkRectangle clip_box; gint x_offset, y_offset; + GdkRegion *full_clip; g_return_if_fail (GDK_IS_WINDOW (window)); @@ -1199,7 +2873,7 @@ gdk_window_end_paint (GdkWindow *window) GdkPaintableIface *iface = GDK_PAINTABLE_GET_IFACE (private->impl); if (iface->end_paint) - iface->end_paint ((GdkPaintable*)private->impl); + iface->end_paint ((GdkPaintable*)private->impl); return; } @@ -1210,38 +2884,46 @@ gdk_window_end_paint (GdkWindow *window) } paint = private->paint_stack->data; - private->paint_stack = g_slist_delete_link (private->paint_stack, - private->paint_stack); + + private->paint_stack = g_slist_delete_link (private->paint_stack, + private->paint_stack); gdk_region_get_clipbox (paint->region, &clip_box); tmp_gc = _gdk_drawable_get_scratch_gc (window, FALSE); - GDK_WINDOW_IMPL_GET_IFACE (private->impl)->get_offsets (window, &x_offset, &y_offset); + x_offset = -private->abs_x; + y_offset = -private->abs_y; - gdk_gc_set_clip_region (tmp_gc, paint->region); - gdk_gc_set_clip_origin (tmp_gc, - x_offset, - y_offset); + if (!paint->uses_implicit) + { + gdk_window_flush_outstanding_moves (window); - gdk_draw_drawable (private->impl, tmp_gc, paint->pixmap, - clip_box.x - paint->x_offset, - clip_box.y - paint->y_offset, - clip_box.x - x_offset, clip_box.y - y_offset, - clip_box.width, clip_box.height); + full_clip = gdk_region_copy (private->clip_region_with_children); + gdk_region_intersect (full_clip, paint->region); + _gdk_gc_set_clip_region_internal (tmp_gc, full_clip, TRUE); /* Takes ownership of full_clip */ + gdk_gc_set_clip_origin (tmp_gc, - x_offset, - y_offset); + gdk_draw_drawable (private->impl, tmp_gc, paint->pixmap, + clip_box.x - paint->x_offset, + clip_box.y - paint->y_offset, + clip_box.x - x_offset, clip_box.y - y_offset, + clip_box.width, clip_box.height); + } if (private->redirect) { - GdkWindowClipData data; - - setup_redirect_clip (window, tmp_gc, &data); + int x_offset, y_offset; + + /* TODO: Should also use paint->region for clipping */ + setup_redirect_clip (window, tmp_gc, &x_offset, &y_offset); gdk_draw_drawable (private->redirect->pixmap, tmp_gc, paint->pixmap, clip_box.x - paint->x_offset, clip_box.y - paint->y_offset, - clip_box.x + data.x_offset, - clip_box.y + data.y_offset, + clip_box.x + x_offset, + clip_box.y + y_offset, clip_box.width, clip_box.height); - reset_redirect_clip (window, tmp_gc, &data); } - + /* Reset clip region of the cached GdkGC */ gdk_gc_set_clip_region (tmp_gc, NULL); @@ -1284,7 +2966,7 @@ static void gdk_window_free_paint_stack (GdkWindow *window) { GdkWindowObject *private = (GdkWindowObject *)window; - + if (private->paint_stack) { GSList *tmp_list = private->paint_stack; @@ -1295,7 +2977,7 @@ gdk_window_free_paint_stack (GdkWindow *window) if (tmp_list == private->paint_stack) g_object_unref (paint->pixmap); - + gdk_region_destroy (paint->region); g_free (paint); @@ -1307,6 +2989,363 @@ gdk_window_free_paint_stack (GdkWindow *window) } } +static void +do_move_region_bits_on_impl (GdkWindowObject *impl_window, + GdkRegion *dest_region, /* In impl window coords */ + int dx, int dy) +{ + GdkGC *tmp_gc; + GdkRectangle copy_rect; + GdkWindowObject *private; + GdkWindowImplIface *impl_iface; + + /* We need to get data from subwindows here, because we might have + * shaped a native window over the moving region (with bg none, + * so the pixels are still there). In fact we might need to get data + * from overlapping native window that are not children of this window, + * so we copy from the toplevel with INCLUDE_INFERIORS. + */ + private = impl_window; + while (!gdk_window_is_toplevel (private)) + { + dx -= private->parent->abs_x + private->x; + dy -= private->parent->abs_y + private->y; + private = gdk_window_get_impl_window (private->parent); + } + tmp_gc = _gdk_drawable_get_subwindow_scratch_gc ((GdkWindow *)private); + + gdk_region_get_clipbox (dest_region, ©_rect); + gdk_gc_set_clip_region (tmp_gc, dest_region); + + /* The region area is moved and we queue translations for all expose events + to the source area that were sent prior to the copy */ + gdk_region_offset (dest_region, -dx, -dy); /* Move to source region */ + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + + impl_iface->queue_translation ((GdkWindow *)impl_window, + tmp_gc, + dest_region, dx, dy); + + gdk_draw_drawable (impl_window->impl, + tmp_gc, + private->impl, + copy_rect.x-dx, copy_rect.y-dy, + copy_rect.x, copy_rect.y, + copy_rect.width, copy_rect.height); + gdk_gc_set_clip_region (tmp_gc, NULL); +} + +static GdkWindowRegionMove * +gdk_window_region_move_new (GdkRegion *region, + int dx, int dy) +{ + GdkWindowRegionMove *move; + + move = g_slice_new (GdkWindowRegionMove); + move->dest_region = gdk_region_copy (region); + move->dx = dx; + move->dy = dy; + + return move; +} + +static void +gdk_window_region_move_free (GdkWindowRegionMove *move) +{ + gdk_region_destroy (move->dest_region); + g_slice_free (GdkWindowRegionMove, move); +} + +static void +append_move_region (GdkWindowObject *impl_window, + GdkRegion *new_dest_region, + int dx, int dy) +{ + GdkWindowRegionMove *move, *old_move; + GdkRegion *new_total_region, *old_total_region; + GdkRegion *source_overlaps_destination; + GdkRegion *non_overwritten; + gboolean added_move; + GList *l, *prev; + + if (gdk_region_empty (new_dest_region)) + return; + + /* In principle this could just append the move to the list of outstanding + moves that will be replayed before drawing anything when we're handling + exposes. However, we'd like to do a bit better since its commonly the case + that we get multiple copies where A is copied to B and then B is copied + to C, and we'd like to express this as a simple copy A to C operation. */ + + /* We approach this by taking the new move and pushing it ahead of moves + starting at the end of the list and stopping when its not safe to do so. + It's not safe to push past a move if either the source of the new move + is in the destination of the old move, or if the destination of the new + move is in the source of the new move, or if the destination of the new + move overlaps the destination of the old move. We simplify this by + just comparing the total regions (src + dest) */ + new_total_region = gdk_region_copy (new_dest_region); + gdk_region_offset (new_total_region, -dx, -dy); + gdk_region_union (new_total_region, new_dest_region); + + added_move = FALSE; + for (l = g_list_last (impl_window->outstanding_moves); l != NULL; l = prev) + { + prev = l->prev; + old_move = l->data; + + old_total_region = gdk_region_copy (old_move->dest_region); + gdk_region_offset (old_total_region, -old_move->dx, -old_move->dy); + gdk_region_union (old_total_region, old_move->dest_region); + + gdk_region_intersect (old_total_region, new_total_region); + /* If these regions intersect then its not safe to push the + new region before the old one */ + if (!gdk_region_empty (old_total_region)) + { + /* The area where the new moves source overlaps the old ones + destination */ + source_overlaps_destination = gdk_region_copy (new_dest_region); + gdk_region_offset (source_overlaps_destination, -dx, -dy); + gdk_region_intersect (source_overlaps_destination, old_move->dest_region); + gdk_region_offset (source_overlaps_destination, dx, dy); + + /* We can do all sort of optimizations here, but to do things safely it becomes + quite complicated. However, a very common case is that you copy something first, + then copy all that or a subset of it to a new location (i.e. if you scroll twice + in the same direction). We'd like to detect this case and optimize it to one + copy. */ + if (gdk_region_equal (source_overlaps_destination, new_dest_region)) + { + /* This means we might be able to replace the old move and the new one + with the new one read from the old ones source, and a second copy of + the non-overwritten parts of the old move. However, such a split + is only valid if the source in the old move isn't overwritten + by the destination of the new one */ + + /* the new destination of old move if split is ok: */ + non_overwritten = gdk_region_copy (old_move->dest_region); + gdk_region_subtract (non_overwritten, new_dest_region); + /* move to source region */ + gdk_region_offset (non_overwritten, -old_move->dx, -old_move->dy); + + gdk_region_intersect (non_overwritten, new_dest_region); + if (gdk_region_empty (non_overwritten)) + { + added_move = TRUE; + move = gdk_window_region_move_new (new_dest_region, + dx + old_move->dx, + dy + old_move->dy); + + impl_window->outstanding_moves = + g_list_insert_before (impl_window->outstanding_moves, + l, move); + gdk_region_subtract (old_move->dest_region, new_dest_region); + } + gdk_region_destroy (non_overwritten); + } + + gdk_region_destroy (source_overlaps_destination); + gdk_region_destroy (old_total_region); + break; + } + gdk_region_destroy (old_total_region); + } + + gdk_region_destroy (new_total_region); + + if (!added_move) + { + move = gdk_window_region_move_new (new_dest_region, dx, dy); + + if (l == NULL) + impl_window->outstanding_moves = + g_list_prepend (impl_window->outstanding_moves, + move); + else + impl_window->outstanding_moves = + g_list_insert_before (impl_window->outstanding_moves, + l->next, move); + } +} + +/* Moves bits and update area by dx/dy in impl window. + Takes ownership of region to avoid copy (because we may change it) */ +static void +move_region_on_impl (GdkWindowObject *impl_window, + GdkRegion *region, /* In impl window coords */ + int dx, int dy) +{ + if ((dx == 0 && dy == 0) || + gdk_region_empty (region)) + { + gdk_region_destroy (region); + return; + } + + g_assert (impl_window == gdk_window_get_impl_window (impl_window)); + + /* Move any old invalid regions in the copy source area by dx/dy */ + if (impl_window->update_area) + { + GdkRegion *update_area; + + update_area = gdk_region_copy (region); + + /* Convert from target to source */ + gdk_region_offset (update_area, -dx, -dy); + gdk_region_intersect (update_area, impl_window->update_area); + /* We only copy the area, so keep the old update area invalid. + It would be safe to remove it too, as code that uses + move_region_on_impl generally also invalidate the source + area. However, it would just use waste cycles. */ + + /* Convert back */ + gdk_region_offset (update_area, dx, dy); + gdk_region_union (impl_window->update_area, update_area); + + /* This area of the destination is now invalid, + so no need to copy to it. */ + gdk_region_subtract (region, update_area); + + gdk_region_destroy (update_area); + } + + /* If we're currently exposing this window, don't copy to this + destination, as it will be overdrawn when the expose is done, + instead invalidate it and repaint later. */ + if (impl_window->implicit_paint) + { + GdkWindowPaint *implicit_paint = impl_window->implicit_paint; + GdkRegion *exposing; + + exposing = gdk_region_copy (implicit_paint->region); + gdk_region_intersect (exposing, region); + gdk_region_subtract (region, exposing); + + impl_window_add_update_area (impl_window, exposing); + gdk_region_destroy (exposing); + } + + if (1) /* Enable flicker free handling of moves. */ + append_move_region (impl_window, region, dx, dy); + else + do_move_region_bits_on_impl (impl_window, + region, dx, dy); + + gdk_region_destroy (region); +} + +/* Flushes all outstanding changes to the window, call this + * before drawing directly to the window (i.e. outside a begin/end_paint pair). + */ +static void +gdk_window_flush_outstanding_moves (GdkWindow *window) +{ + GdkWindowObject *private; + GdkWindowObject *impl_window; + GList *l; + GdkWindowRegionMove *move; + + private = (GdkWindowObject *) window; + + impl_window = gdk_window_get_impl_window (private); + + for (l = impl_window->outstanding_moves; l != NULL; l = l->next) + { + move = l->data; + + do_move_region_bits_on_impl (impl_window, + move->dest_region, move->dx, move->dy); + + gdk_window_region_move_free (move); + } + + g_list_free (impl_window->outstanding_moves); + impl_window->outstanding_moves = NULL; +} + +/** + * gdk_window_flush: + * @window: a #GdkWindow + * + * Flush all outstanding cached operations on a window, leaving the + * window in a state which reflects all that has been drawn before. + * + * Gdk uses multiple kinds of caching to get better performance and + * nicer drawing. For instance, during exposes all paints to a window + * using double buffered rendering are keep on a pixmap until the last + * window has been exposed. It also delays window moves/scrolls until + * as long as possible until next update to avoid tearing when moving + * windows. + * + * Normally this should be completely invisible to applications, as + * we automatically flush the windows when required, but this might + * be needed if you for instance mix direct native drawing with + * gdk drawing. For Gtk widgets that don't use double buffering this + * will be called automatically before sending the expose event. + * + * Since: 2.18 + **/ +void +gdk_window_flush (GdkWindow *window) +{ + gdk_window_flush_outstanding_moves (window); + gdk_window_flush_implicit_paint (window); +} + +/* If we're about to move/resize or otherwise change the + * hierarchy of a client side window in an impl and we're + * called from an expose event handler then we need to + * flush any already painted parts of the implicit paint + * that are not part of the current paint, as these may + * be used when scrolling or may overdraw the changes + * caused by the hierarchy change. + */ +static void +gdk_window_flush_if_exposing (GdkWindow *window) +{ + GdkWindowObject *private; + GdkWindowObject *impl_window; + GList *l; + GdkWindowRegionMove *move; + + private = (GdkWindowObject *) window; + impl_window = gdk_window_get_impl_window (private); + + /* If we're in an implicit paint (i.e. in an expose handler, flush + all the already finished exposes to get things to an uptodate state. */ + if (impl_window->implicit_paint) + gdk_window_flush (window); +} + + +static void +gdk_window_flush_recursive_helper (GdkWindowObject *window, + GdkWindow *impl) +{ + GdkWindowObject *child; + GList *l; + + for (l = window->children; l != NULL; l = l->next) + { + child = l->data; + + if (child->impl == impl) + /* Same impl, ignore */ + gdk_window_flush_recursive_helper (child, impl); + else + gdk_window_flush_recursive (child); + } +} + +static void +gdk_window_flush_recursive (GdkWindowObject *window) +{ + gdk_window_flush ((GdkWindow *)window); + gdk_window_flush_recursive_helper (window, window->impl); +} + static void gdk_window_get_offsets (GdkWindow *window, gint *x_offset, @@ -1321,21 +3360,24 @@ gdk_window_get_offsets (GdkWindow *window, *y_offset = paint->y_offset; } else - GDK_WINDOW_IMPL_GET_IFACE (private->impl)->get_offsets (window, x_offset, y_offset); + { + *x_offset = -private->abs_x; + *y_offset = -private->abs_y; + } } /** * gdk_window_get_internal_paint_info: * @window: a #GdkWindow - * @real_drawable: location to store the drawable to which drawing should be + * @real_drawable: location to store the drawable to which drawing should be * done. * @x_offset: location to store the X offset between coordinates in @window, - * and the underlying window system primitive coordinates for + * and the underlying window system primitive coordinates for * *@real_drawable. * @y_offset: location to store the Y offset between coordinates in @window, * and the underlying window system primitive coordinates for * *@real_drawable. - * + * * If you bypass the GDK layer and use windowing system primitives to * draw directly onto a #GdkWindow, then you need to deal with two * details: there may be an offset between GDK coordinates and windowing @@ -1354,7 +3396,7 @@ gdk_window_get_internal_paint_info (GdkWindow *window, gint *y_offset) { gint x_off, y_off; - + GdkWindowObject *private; g_return_if_fail (GDK_IS_WINDOW (window)); @@ -1369,7 +3411,12 @@ gdk_window_get_internal_paint_info (GdkWindow *window, *real_drawable = paint->pixmap; } else - *real_drawable = window; + { + /* This means you're probably gonna be doing some weird shit + directly to the window, so we flush all outstanding stuff */ + gdk_window_flush (window); + *real_drawable = window; + } } gdk_window_get_offsets (window, &x_off, &y_off); @@ -1380,40 +3427,127 @@ gdk_window_get_internal_paint_info (GdkWindow *window, *y_offset = y_off; } -#define OFFSET_GC(gc) \ - gint x_offset, y_offset; \ - gint old_clip_x = gc->clip_x_origin; \ - gint old_clip_y = gc->clip_y_origin; \ - gint old_ts_x = gc->ts_x_origin; \ - gint old_ts_y = gc->ts_y_origin; \ - gdk_window_get_offsets (drawable, &x_offset, &y_offset); \ - if (x_offset != 0 || y_offset != 0) \ - { \ - gdk_gc_set_clip_origin (gc, old_clip_x - x_offset, \ - old_clip_y - y_offset); \ - gdk_gc_set_ts_origin (gc, old_ts_x - x_offset, \ - old_ts_y - y_offset); \ - } +static GdkDrawable * +start_draw_helper (GdkDrawable *drawable, + GdkGC *gc, + gint *x_offset_out, + gint *y_offset_out) +{ + GdkWindowObject *private = (GdkWindowObject *)drawable; + gint x_offset, y_offset; + GdkDrawable *impl; + gint old_clip_x = gc->clip_x_origin; + gint old_clip_y = gc->clip_y_origin; + GdkRegion *clip; + guint32 clip_region_tag; + GdkWindowPaint *paint; -#define RESTORE_GC(gc) \ - if (x_offset != 0 || y_offset != 0) \ + paint = NULL; + if (private->paint_stack) + paint = private->paint_stack->data; + + if (paint) + { + x_offset = paint->x_offset; + y_offset = paint->y_offset; + } + else + { + x_offset = -private->abs_x; + y_offset = -private->abs_y; + } + + if (x_offset != 0 || y_offset != 0) + { + gdk_gc_set_clip_origin (gc, + old_clip_x - x_offset, + old_clip_y - y_offset); + gdk_gc_set_ts_origin (gc, + gc->ts_x_origin - x_offset, + gc->ts_y_origin - y_offset); + } + + *x_offset_out = x_offset; + *y_offset_out = y_offset; + + /* Add client side window clip region to gc */ + clip = NULL; + if (paint) + { + /* Only need clipping if using implicit paint, otherwise + the pixmap is clipped when copying to the window in end_paint */ + if (paint->uses_implicit) + { + /* This includes the window clip */ + clip = paint->region; + } + clip_region_tag = paint->region_tag; + + /* After having set up the drawable clip rect on a GC we need to make sure + * that we draw to th the impl, otherwise the pixmap code will reset the + * drawable clip. */ + impl = ((GdkPixmapObject *)(paint->pixmap))->impl; + } + else + { + /* Drawing directly to the window, flush anything outstanding to + guarantee ordering. */ + gdk_window_flush ((GdkWindow *)drawable); + + /* Don't clip when drawing to root or all native */ + if (!_gdk_native_windows && private->window_type != GDK_WINDOW_ROOT) + { + if (_gdk_gc_get_subwindow (gc) == GDK_CLIP_BY_CHILDREN) + clip = private->clip_region_with_children; + else + clip = private->clip_region; + } + clip_region_tag = private->clip_tag; + impl = private->impl; + } + + if (clip) + _gdk_gc_add_drawable_clip (gc, + clip_region_tag, clip, + /* If there was a clip origin set appart from the + * window offset, need to take that into + * consideration */ + -old_clip_x, -old_clip_y); + + return impl; +} + +#define BEGIN_DRAW \ + { \ + GdkDrawable *impl; \ + gint x_offset, y_offset; \ + gint old_clip_x = gc->clip_x_origin; \ + gint old_clip_y = gc->clip_y_origin; \ + gint old_ts_x = gc->ts_x_origin; \ + gint old_ts_y = gc->ts_y_origin; \ + impl = start_draw_helper (drawable, gc, \ + &x_offset, &y_offset); + +#define END_DRAW \ + if (x_offset != 0 || y_offset != 0) \ { \ gdk_gc_set_clip_origin (gc, old_clip_x, old_clip_y); \ gdk_gc_set_ts_origin (gc, old_ts_x, old_ts_y); \ - } + } \ + } static GdkGC * gdk_window_create_gc (GdkDrawable *drawable, - GdkGCValues *values, - GdkGCValuesMask mask) + GdkGCValues *values, + GdkGCValuesMask mask) { g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL); - + if (GDK_WINDOW_DESTROYED (drawable)) return NULL; return gdk_gc_new_with_values (((GdkWindowObject *) drawable)->impl, - values, mask); + values, mask); } static void @@ -1425,23 +3559,13 @@ gdk_window_draw_rectangle (GdkDrawable *drawable, gint width, gint height) { - GdkWindowObject *private = (GdkWindowObject *)drawable; - OFFSET_GC (gc); - if (GDK_WINDOW_DESTROYED (drawable)) return; - - if (private->paint_stack) - { - GdkWindowPaint *paint = private->paint_stack->data; - gdk_draw_rectangle (paint->pixmap, gc, filled, - x - x_offset, y - y_offset, width, height); - } - else - gdk_draw_rectangle (private->impl, gc, filled, - x - x_offset, y - y_offset, width, height); - RESTORE_GC (gc); + BEGIN_DRAW; + gdk_draw_rectangle (impl, gc, filled, + x - x_offset, y - y_offset, width, height); + END_DRAW; } static void @@ -1455,24 +3579,14 @@ gdk_window_draw_arc (GdkDrawable *drawable, gint angle1, gint angle2) { - GdkWindowObject *private = (GdkWindowObject *)drawable; - OFFSET_GC (gc); - if (GDK_WINDOW_DESTROYED (drawable)) return; - - if (private->paint_stack) - { - GdkWindowPaint *paint = private->paint_stack->data; - gdk_draw_arc (paint->pixmap, gc, filled, - x - x_offset, y - y_offset, - width, height, angle1, angle2); - } - else - gdk_draw_arc (private->impl, gc, filled, - x - x_offset, y - y_offset, - width, height, angle1, angle2); - RESTORE_GC (gc); + + BEGIN_DRAW; + gdk_draw_arc (impl, gc, filled, + x - x_offset, y - y_offset, + width, height, angle1, angle2); + END_DRAW; } static void @@ -1482,18 +3596,17 @@ gdk_window_draw_polygon (GdkDrawable *drawable, GdkPoint *points, gint npoints) { - GdkWindowObject *private = (GdkWindowObject *)drawable; GdkPoint *new_points; - - OFFSET_GC (gc); if (GDK_WINDOW_DESTROYED (drawable)) return; - + + BEGIN_DRAW; + if (x_offset != 0 || y_offset != 0) { int i; - + new_points = g_new (GdkPoint, npoints); for (i=0; ipaint_stack) - { - GdkWindowPaint *paint = private->paint_stack->data; - gdk_draw_polygon (paint->pixmap, gc, filled, new_points, npoints); + gdk_draw_polygon (impl, gc, filled, new_points, npoints); - } - else - gdk_draw_polygon (private->impl, gc, filled, new_points, npoints); - if (new_points != points) g_free (new_points); - RESTORE_GC (gc); + END_DRAW; } static void @@ -1528,24 +3634,13 @@ gdk_window_draw_text (GdkDrawable *drawable, const gchar *text, gint text_length) { - GdkWindowObject *private = (GdkWindowObject *)drawable; - OFFSET_GC (gc); - if (GDK_WINDOW_DESTROYED (drawable)) return; - - if (private->paint_stack) - { - GdkWindowPaint *paint = private->paint_stack->data; - gdk_draw_text (paint->pixmap, font, gc, - x - x_offset, y - y_offset, text, text_length); - } - else - gdk_draw_text (private->impl, font, gc, - x - x_offset, y - y_offset, text, text_length); - - RESTORE_GC (gc); + BEGIN_DRAW; + gdk_draw_text (impl, font, gc, + x - x_offset, y - y_offset, text, text_length); + END_DRAW; } static void @@ -1557,33 +3652,36 @@ gdk_window_draw_text_wc (GdkDrawable *drawable, const GdkWChar *text, gint text_length) { - GdkWindowObject *private = (GdkWindowObject *)drawable; - OFFSET_GC (gc); - if (GDK_WINDOW_DESTROYED (drawable)) return; - - if (private->paint_stack) - { - GdkWindowPaint *paint = private->paint_stack->data; - gdk_draw_text_wc (paint->pixmap, font, gc, - x - x_offset, y - y_offset, text, text_length); - } - else - gdk_draw_text_wc (private->impl, font, gc, - x - x_offset, y - y_offset, text, text_length); - - RESTORE_GC (gc); + + BEGIN_DRAW; + gdk_draw_text_wc (impl, font, gc, + x - x_offset, y - y_offset, text, text_length); + END_DRAW; } -static GdkDrawable* +static GdkDrawable * +gdk_window_get_source_drawable (GdkDrawable *drawable) +{ + GdkWindow *window = GDK_WINDOW (drawable); + GdkWindowObject *private; + + private = (GdkWindowObject *) window; + if (GDK_DRAWABLE_GET_CLASS (private->impl)->get_source_drawable) + return GDK_DRAWABLE_GET_CLASS (private->impl)->get_source_drawable (private->impl); + + return drawable; +} + +static GdkDrawable * gdk_window_get_composite_drawable (GdkDrawable *drawable, - gint x, - gint y, - gint width, - gint height, - gint *composite_x_offset, - gint *composite_y_offset) + gint x, + gint y, + gint width, + gint height, + gint *composite_x_offset, + gint *composite_y_offset) { GdkWindowObject *private = (GdkWindowObject *)drawable; GSList *list; @@ -1591,19 +3689,17 @@ gdk_window_get_composite_drawable (GdkDrawable *drawable, GdkRectangle rect; GdkGC *tmp_gc; gboolean overlap_buffer; + GdkDrawable *source; + GdkWindowObject *impl_window; + GdkWindowPaint *implicit_paint; - GDK_WINDOW_IMPL_GET_IFACE (private->impl)->get_offsets (GDK_WINDOW (drawable), - composite_x_offset, - composite_y_offset); - - if ((GDK_IS_WINDOW (drawable) && GDK_WINDOW_DESTROYED (drawable)) - || private->paint_stack == NULL) - { - /* No backing store */ - return g_object_ref (drawable); - } + *composite_x_offset = -private->abs_x; + *composite_y_offset = -private->abs_y; - /* See if the buffered part is overlapping the part we want + if ((GDK_IS_WINDOW (drawable) && GDK_WINDOW_DESTROYED (drawable))) + return g_object_ref (_gdk_drawable_get_source_drawable (drawable)); + + /* See if any buffered part is overlapping the part we want * to get */ rect.x = x; @@ -1612,7 +3708,7 @@ gdk_window_get_composite_drawable (GdkDrawable *drawable, rect.height = height; overlap_buffer = FALSE; - + for (list = private->paint_stack; list != NULL; list = list->next) { GdkWindowPaint *paint = list->data; @@ -1624,7 +3720,7 @@ gdk_window_get_composite_drawable (GdkDrawable *drawable, { *composite_x_offset = paint->x_offset; *composite_y_offset = paint->y_offset; - + return g_object_ref (paint->pixmap); } else if (overlap == GDK_OVERLAP_RECTANGLE_PART) @@ -1634,29 +3730,68 @@ gdk_window_get_composite_drawable (GdkDrawable *drawable, } } + impl_window = gdk_window_get_impl_window (private); + implicit_paint = impl_window->implicit_paint; + if (implicit_paint) + { + GdkOverlapType overlap; + + rect.x += private->abs_x; + rect.y += private->abs_y; + + overlap = gdk_region_rect_in (implicit_paint->region, &rect); + if (overlap == GDK_OVERLAP_RECTANGLE_IN) + { + *composite_x_offset = -private->abs_x + implicit_paint->x_offset; + *composite_y_offset = -private->abs_y + implicit_paint->y_offset; + + return g_object_ref (implicit_paint->pixmap); + } + else if (overlap == GDK_OVERLAP_RECTANGLE_PART) + overlap_buffer = TRUE; + } + if (!overlap_buffer) - return g_object_ref (drawable); + return g_object_ref (_gdk_drawable_get_source_drawable (drawable)); tmp_pixmap = gdk_pixmap_new (drawable, width, height, -1); tmp_gc = _gdk_drawable_get_scratch_gc (tmp_pixmap, FALSE); + source = _gdk_drawable_get_source_drawable (drawable); + /* Copy the current window contents */ gdk_draw_drawable (tmp_pixmap, - tmp_gc, - private->impl, - x - *composite_x_offset, - y - *composite_y_offset, - 0, 0, - width, height); + tmp_gc, + GDK_WINDOW_OBJECT (source)->impl, + x - *composite_x_offset, + y - *composite_y_offset, + 0, 0, + width, height); /* paint the backing stores */ - for (list = private->paint_stack; list != NULL; list = list->next) + if (implicit_paint) { GdkWindowPaint *paint = list->data; + gdk_gc_set_clip_region (tmp_gc, paint->region); + gdk_gc_set_clip_origin (tmp_gc, -x - paint->x_offset, -y - paint->y_offset); + + gdk_draw_drawable (tmp_pixmap, tmp_gc, paint->pixmap, + x - paint->x_offset, + y - paint->y_offset, + 0, 0, width, height); + } + + for (list = private->paint_stack; list != NULL; list = list->next) + { + GdkWindowPaint *paint = list->data; + + if (paint->uses_implicit) + continue; /* We already copied this above */ + gdk_gc_set_clip_region (tmp_gc, paint->region); gdk_gc_set_clip_origin (tmp_gc, -x, -y); - + gdk_draw_drawable (tmp_pixmap, tmp_gc, paint->pixmap, x - paint->x_offset, y - paint->y_offset, @@ -1679,7 +3814,7 @@ gdk_window_get_clip_region (GdkDrawable *drawable) GdkWindowObject *private = (GdkWindowObject *)drawable; GdkRegion *result; - result = gdk_drawable_get_clip_region (private->impl); + result = gdk_region_copy (private->clip_region); if (private->paint_stack) { @@ -1689,10 +3824,10 @@ gdk_window_get_clip_region (GdkDrawable *drawable) while (tmp_list) { GdkWindowPaint *paint = tmp_list->data; - + gdk_region_union (paint_region, paint->region); - tmp_list = tmp_list->next; + tmp_list = tmp_list->next; } gdk_region_intersect (result, paint_region); @@ -1706,8 +3841,8 @@ static GdkRegion* gdk_window_get_visible_region (GdkDrawable *drawable) { GdkWindowObject *private = (GdkWindowObject*) drawable; - - return gdk_drawable_get_visible_region (private->impl); + + return gdk_region_copy (private->clip_region); } static void @@ -1719,30 +3854,83 @@ gdk_window_draw_drawable (GdkDrawable *drawable, gint xdest, gint ydest, gint width, - gint height) + gint height, + GdkDrawable *original_src) { GdkWindowObject *private = (GdkWindowObject *)drawable; - OFFSET_GC (gc); - + if (GDK_WINDOW_DESTROYED (drawable)) return; - /* If we have a backing pixmap draw to that */ - if (private->paint_stack) + BEGIN_DRAW; + + /* Call the method directly to avoid getting the composite drawable again */ + GDK_DRAWABLE_GET_CLASS (impl)->draw_drawable_with_src (impl, gc, + src, + xsrc, ysrc, + xdest - x_offset, + ydest - y_offset, + width, height, + original_src); + + if (!private->paint_stack) { - GdkWindowPaint *paint = private->paint_stack->data; - gdk_draw_drawable (paint->pixmap, gc, - src, xsrc, ysrc, - xdest - x_offset, ydest - y_offset, width, height); + /* We might have drawn from an obscured part of a client + side window, if so we need to send graphics exposures */ + if (_gdk_gc_get_exposures (gc) && + GDK_IS_WINDOW (original_src)) + { + GdkRegion *exposure_region; + GdkRegion *clip; + GdkRectangle r; + r.x = xdest; + r.y = ydest; + r.width = width; + r.height = height; + exposure_region = gdk_region_rectangle (&r); + + if (_gdk_gc_get_subwindow (gc) == GDK_CLIP_BY_CHILDREN) + clip = private->clip_region_with_children; + else + clip = private->clip_region; + gdk_region_intersect (exposure_region, clip); + + _gdk_gc_remove_drawable_clip (gc); + clip = _gdk_gc_get_clip_region (gc); + if (clip) + { + gdk_region_offset (exposure_region, + old_clip_x, + old_clip_y); + gdk_region_intersect (exposure_region, clip); + gdk_region_offset (exposure_region, + -old_clip_x, + -old_clip_y); + } + + /* Note: We don't clip by the clip mask if set, so this + may invalidate to much */ + + /* Remove the area that is correctly copied from the src. + * Note that xsrc/ysrc has been corrected for abs_x/y offsets already, + * which need to be undone */ + clip = gdk_drawable_get_visible_region (original_src); + gdk_region_offset (clip, + xdest - (xsrc - GDK_WINDOW_OBJECT (original_src)->abs_x), + ydest - (ysrc - GDK_WINDOW_OBJECT (original_src)->abs_y)); + gdk_region_subtract (exposure_region, clip); + gdk_region_destroy (clip); + + gdk_window_invalidate_region (GDK_WINDOW (private), + exposure_region, + _gdk_gc_get_subwindow (gc) == GDK_INCLUDE_INFERIORS); + + gdk_region_destroy (exposure_region); + } } - else - gdk_draw_drawable (private->impl, gc, - src, xsrc, ysrc, - xdest - x_offset, ydest - y_offset, - width, height); - RESTORE_GC (gc); + END_DRAW; } static void @@ -1751,14 +3939,13 @@ gdk_window_draw_points (GdkDrawable *drawable, GdkPoint *points, gint npoints) { - GdkWindowObject *private = (GdkWindowObject *)drawable; GdkPoint *new_points; - - OFFSET_GC (gc); if (GDK_WINDOW_DESTROYED (drawable)) return; - + + BEGIN_DRAW; + if (x_offset != 0 || y_offset != 0) { gint i; @@ -1773,18 +3960,12 @@ gdk_window_draw_points (GdkDrawable *drawable, else new_points = points; - if (private->paint_stack) - { - GdkWindowPaint *paint = private->paint_stack->data; - gdk_draw_points (paint->pixmap, gc, new_points, npoints); - } - else - gdk_draw_points (private->impl, gc, points, npoints); + gdk_draw_points (impl, gc, new_points, npoints); if (new_points != points) g_free (new_points); - RESTORE_GC (gc); + END_DRAW; } static void @@ -1793,14 +3974,13 @@ gdk_window_draw_segments (GdkDrawable *drawable, GdkSegment *segs, gint nsegs) { - GdkWindowObject *private = (GdkWindowObject *)drawable; GdkSegment *new_segs; - OFFSET_GC (gc); - if (GDK_WINDOW_DESTROYED (drawable)) return; - + + BEGIN_DRAW; + if (x_offset != 0 || y_offset != 0) { gint i; @@ -1817,18 +3997,12 @@ gdk_window_draw_segments (GdkDrawable *drawable, else new_segs = segs; - if (private->paint_stack) - { - GdkWindowPaint *paint = private->paint_stack->data; - gdk_draw_segments (paint->pixmap, gc, new_segs, nsegs); - } - else - gdk_draw_segments (private->impl, gc, new_segs, nsegs); - + gdk_draw_segments (impl, gc, new_segs, nsegs); + if (new_segs != segs) g_free (new_segs); - RESTORE_GC (gc); + END_DRAW; } static void @@ -1837,14 +4011,13 @@ gdk_window_draw_lines (GdkDrawable *drawable, GdkPoint *points, gint npoints) { - GdkWindowObject *private = (GdkWindowObject *)drawable; GdkPoint *new_points; - OFFSET_GC (gc); - if (GDK_WINDOW_DESTROYED (drawable)) return; - + + BEGIN_DRAW; + if (x_offset != 0 || y_offset != 0) { gint i; @@ -1859,18 +4032,12 @@ gdk_window_draw_lines (GdkDrawable *drawable, else new_points = points; - if (private->paint_stack) - { - GdkWindowPaint *paint = private->paint_stack->data; - gdk_draw_lines (paint->pixmap, gc, new_points, npoints); - } - else - gdk_draw_lines (private->impl, gc, new_points, npoints); + gdk_draw_lines (impl, gc, new_points, npoints); if (new_points != points) g_free (new_points); - RESTORE_GC (gc); + END_DRAW; } static void @@ -1881,24 +4048,13 @@ gdk_window_draw_glyphs (GdkDrawable *drawable, gint y, PangoGlyphString *glyphs) { - GdkWindowObject *private = (GdkWindowObject *)drawable; - - OFFSET_GC (gc); - if (GDK_WINDOW_DESTROYED (drawable)) return; - - if (private->paint_stack) - { - GdkWindowPaint *paint = private->paint_stack->data; - gdk_draw_glyphs (paint->pixmap, gc, font, x - x_offset, y - y_offset, glyphs); - } - else - gdk_draw_glyphs (private->impl, gc, font, - x - x_offset, y - y_offset, glyphs); - - RESTORE_GC (gc); + BEGIN_DRAW; + gdk_draw_glyphs (impl, gc, font, + x - x_offset, y - y_offset, glyphs); + END_DRAW; } static void @@ -1910,14 +4066,13 @@ gdk_window_draw_glyphs_transformed (GdkDrawable *drawable, gint y, PangoGlyphString *glyphs) { - GdkWindowObject *private = (GdkWindowObject *)drawable; PangoMatrix tmp_matrix; - OFFSET_GC (gc); - if (GDK_WINDOW_DESTROYED (drawable)) return; + BEGIN_DRAW; + if (x_offset != 0 || y_offset != 0) { if (matrix) @@ -1930,7 +4085,7 @@ gdk_window_draw_glyphs_transformed (GdkDrawable *drawable, else if (GDK_PANGO_UNITS_OVERFLOWS (x_offset, y_offset)) { PangoMatrix identity = PANGO_MATRIX_INIT; - + tmp_matrix = identity; tmp_matrix.x0 -= x_offset; tmp_matrix.y0 -= y_offset; @@ -1942,17 +4097,10 @@ gdk_window_draw_glyphs_transformed (GdkDrawable *drawable, y -= y_offset * PANGO_SCALE; } } - - if (private->paint_stack) - { - GdkWindowPaint *paint = private->paint_stack->data; - gdk_draw_glyphs_transformed (paint->pixmap, gc, matrix, font, x, y, glyphs); - } - else - gdk_draw_glyphs_transformed (private->impl, gc, matrix, font, x, y, glyphs); + gdk_draw_glyphs_transformed (impl, gc, matrix, font, x, y, glyphs); - RESTORE_GC (gc); + END_DRAW; } typedef struct { @@ -2039,15 +4187,14 @@ setup_backing_rect_method (BackingRectMethod *method, GdkWindow *window, GdkWind } static void -gdk_window_clear_backing_rect (GdkWindow *window, - gint x, - gint y, - gint width, - gint height) +gdk_window_clear_backing_region (GdkWindow *window, + GdkRegion *region) { GdkWindowObject *private = (GdkWindowObject *)window; GdkWindowPaint *paint = private->paint_stack->data; BackingRectMethod method; + GdkRegion *clip; + GdkRectangle clipbox; #if 0 GTimer *timer; double elapsed; @@ -2064,14 +4211,16 @@ gdk_window_clear_backing_rect (GdkWindow *window, method.gc = NULL; setup_backing_rect_method (&method, window, paint, 0, 0); + clip = gdk_region_copy (paint->region); + gdk_region_intersect (clip, region); + gdk_region_get_clipbox (clip, &clipbox); + + if (method.cr) { g_assert (method.gc == NULL); - cairo_rectangle (method.cr, x, y, width, height); - cairo_clip (method.cr); - - gdk_cairo_region (method.cr, paint->region); + gdk_cairo_region (method.cr, clip); cairo_fill (method.cr); cairo_destroy (method.cr); @@ -2084,8 +4233,10 @@ gdk_window_clear_backing_rect (GdkWindow *window, { g_assert (method.gc != NULL); - gdk_gc_set_clip_region (method.gc, paint->region); - gdk_draw_rectangle (window, method.gc, TRUE, x, y, width, height); + gdk_gc_set_clip_region (method.gc, clip); + gdk_draw_rectangle (window, method.gc, TRUE, + clipbox.x, clipbox.y, + clipbox.width, clipbox.height); g_object_unref (method.gc); #if 0 @@ -2094,46 +4245,46 @@ gdk_window_clear_backing_rect (GdkWindow *window, #endif } + gdk_region_destroy (clip); + #if 0 g_timer_destroy (timer); #endif } static void -gdk_window_clear_backing_rect_redirect (GdkWindow *window, - gint x, - gint y, - gint width, - gint height) +gdk_window_clear_backing_region_redirect (GdkWindow *window, + GdkRegion *region) { GdkWindowObject *private = (GdkWindowObject *)window; GdkWindowRedirect *redirect = private->redirect; GdkRegion *clip_region; + GdkRectangle clipbox; gint x_offset, y_offset; BackingRectMethod method; GdkWindowPaint paint; - + if (GDK_WINDOW_DESTROYED (window)) return; - paint.x_offset = 0; - paint.y_offset = 0; - paint.pixmap = redirect->pixmap; - paint.surface = _gdk_drawable_ref_cairo_surface (redirect->pixmap); - clip_region = _gdk_window_calculate_full_clip_region (window, GDK_WINDOW (redirect->redirected), - NULL, TRUE, + TRUE, &x_offset, &y_offset); + gdk_region_intersect (clip_region, region); + /* offset is from redirected window origin to window origin, convert to the offset from the redirected pixmap origin to the window origin */ x_offset += redirect->dest_x - redirect->src_x; y_offset += redirect->dest_y - redirect->src_y; - /* Convert region and rect to pixmap coords */ + /* Convert region to pixmap coords */ gdk_region_offset (clip_region, x_offset, y_offset); - x += x_offset; - y += y_offset; + + paint.x_offset = 0; + paint.y_offset = 0; + paint.pixmap = redirect->pixmap; + paint.surface = _gdk_drawable_ref_cairo_surface (redirect->pixmap); method.cr = NULL; method.gc = NULL; @@ -2143,9 +4294,6 @@ gdk_window_clear_backing_rect_redirect (GdkWindow *window, { g_assert (method.gc == NULL); - cairo_rectangle (method.cr, x, y, width, height); - cairo_clip (method.cr); - gdk_cairo_region (method.cr, clip_region); cairo_fill (method.cr); @@ -2155,8 +4303,11 @@ gdk_window_clear_backing_rect_redirect (GdkWindow *window, { g_assert (method.gc != NULL); + gdk_region_get_clipbox (clip_region, &clipbox); gdk_gc_set_clip_region (method.gc, clip_region); - gdk_draw_rectangle (redirect->pixmap, method.gc, TRUE, x, y, width, height); + gdk_draw_rectangle (redirect->pixmap, method.gc, TRUE, + clipbox.x, clipbox.y, + clipbox.width, clipbox.height); g_object_unref (method.gc); } @@ -2165,11 +4316,62 @@ gdk_window_clear_backing_rect_redirect (GdkWindow *window, cairo_surface_destroy (paint.surface); } +static void +gdk_window_clear_backing_region_direct (GdkWindow *window, + GdkRegion *region) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + BackingRectMethod method; + GdkWindowPaint paint; + GdkRegion *clip; + GdkRectangle clipbox; + + if (GDK_WINDOW_DESTROYED (window)) + return; + + paint.x_offset = 0; + paint.y_offset = 0; + paint.pixmap = window; + paint.surface = _gdk_drawable_ref_cairo_surface (window); + + method.cr = NULL; + method.gc = NULL; + setup_backing_rect_method (&method, window, &paint, 0, 0); + + clip = gdk_region_copy (private->clip_region_with_children); + gdk_region_intersect (clip, region); + gdk_region_get_clipbox (clip, &clipbox); + + if (method.cr) + { + g_assert (method.gc == NULL); + + gdk_cairo_region (method.cr, clip); + cairo_fill (method.cr); + + cairo_destroy (method.cr); + } + else + { + g_assert (method.gc != NULL); + + gdk_gc_set_clip_region (method.gc, clip); + gdk_draw_rectangle (window, method.gc, TRUE, + clipbox.x, clipbox.y, + clipbox.width, clipbox.height); + g_object_unref (method.gc); + + } + + gdk_region_destroy (clip); + cairo_surface_destroy (paint.surface); +} + /** * gdk_window_clear: * @window: a #GdkWindow - * + * * Clears an entire @window to the background color or background pixmap. **/ void @@ -2180,9 +4382,98 @@ gdk_window_clear (GdkWindow *window) g_return_if_fail (GDK_IS_WINDOW (window)); gdk_drawable_get_size (GDK_DRAWABLE (window), &width, &height); - + gdk_window_clear_area (window, 0, 0, - width, height); + width, height); +} + +static gboolean +clears_on_native (GdkWindowObject *private) +{ + GdkWindowObject *next; + + next = private; + do + { + private = next; + if (gdk_window_has_impl (private)) + return TRUE; + next = private->parent; + } + while (private->bg_pixmap == GDK_PARENT_RELATIVE_BG && + next && next->window_type != GDK_WINDOW_ROOT); + return FALSE; +} + +static void +gdk_window_clear_region_internal (GdkWindow *window, + GdkRegion *region, + gboolean send_expose) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowImplIface *impl_iface; + + if (private->paint_stack) + gdk_window_clear_backing_region (window, region); + else + { + if (private->redirect) + gdk_window_clear_backing_region_redirect (window, region); + + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + + if (impl_iface->clear_region && clears_on_native (private)) + { + GdkRegion *copy; + copy = gdk_region_copy (region); + gdk_region_intersect (copy, + private->clip_region_with_children); + + impl_iface->clear_region (window, copy, send_expose); + + gdk_region_destroy (copy); + } + else + { + gdk_window_clear_backing_region_direct (window, region); + if (send_expose) + gdk_window_invalidate_region (window, region, FALSE); + } + } +} + +static void +gdk_window_clear_area_internal (GdkWindow *window, + gint x, + gint y, + gint width, + gint height, + gboolean send_expose) +{ + GdkRectangle rect; + GdkRegion *region; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + if (GDK_WINDOW_DESTROYED (window)) + return; + + /* Terminate early to avoid weird interpretation of + zero width/height by XClearArea */ + if (width == 0 || height == 0) + return; + + rect.x = x; + rect.y = y; + rect.width = width; + rect.height = height; + + region = gdk_region_rectangle (&rect); + gdk_window_clear_region_internal (window, + region, + FALSE); + gdk_region_destroy (region); + } /** @@ -2194,7 +4485,7 @@ gdk_window_clear (GdkWindow *window) * @height: height of rectangle to clear * * Clears an area of @window to the background color or background pixmap. - * + * **/ void gdk_window_clear_area (GdkWindow *window, @@ -2203,22 +4494,10 @@ gdk_window_clear_area (GdkWindow *window, gint width, gint height) { - GdkWindowObject *private = (GdkWindowObject *)window; - - g_return_if_fail (GDK_IS_WINDOW (window)); - - if (private->paint_stack) - gdk_window_clear_backing_rect (window, x, y, width, height); - else - { - if (private->redirect) - gdk_window_clear_backing_rect_redirect (window, x, y, width, height); - - GDK_WINDOW_IMPL_GET_IFACE (private->impl)->clear_area (window, - x, y, - width, height, - FALSE); - } + gdk_window_clear_area_internal (window, + x, y, + width, height, + FALSE); } /** @@ -2234,63 +4513,40 @@ gdk_window_clear_area (GdkWindow *window, * * This function has a stupid name because it dates back to the mists * time, pre-GDK-1.0. - * + * **/ void gdk_window_clear_area_e (GdkWindow *window, - gint x, - gint y, - gint width, - gint height) + gint x, + gint y, + gint width, + gint height) { - GdkWindowObject *private = (GdkWindowObject *)window; - - g_return_if_fail (GDK_IS_WINDOW (window)); - - if (private->paint_stack) - gdk_window_clear_backing_rect (window, x, y, width, height); - - if (private->redirect) - gdk_window_clear_backing_rect_redirect (window, x, y, width, height); - - GDK_WINDOW_IMPL_GET_IFACE (private->impl)->clear_area (window, - x, y, - width, height, - TRUE); + gdk_window_clear_area_internal (window, + x, y, + width, height, + TRUE); } static void gdk_window_draw_image (GdkDrawable *drawable, - GdkGC *gc, - GdkImage *image, - gint xsrc, - gint ysrc, - gint xdest, - gint ydest, - gint width, - gint height) + GdkGC *gc, + GdkImage *image, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height) { - GdkWindowObject *private = (GdkWindowObject *)drawable; - - OFFSET_GC (gc); - if (GDK_WINDOW_DESTROYED (drawable)) return; - - if (private->paint_stack) - { - GdkWindowPaint *paint = private->paint_stack->data; - gdk_draw_image (paint->pixmap, gc, image, xsrc, ysrc, - xdest - x_offset, ydest - y_offset, - width, height); - } - else - gdk_draw_image (private->impl, gc, image, xsrc, ysrc, - xdest - x_offset, ydest - y_offset, - width, height); - - RESTORE_GC (gc); + BEGIN_DRAW; + gdk_draw_image (impl, gc, image, xsrc, ysrc, + xdest - x_offset, ydest - y_offset, + width, height); + END_DRAW; } static void @@ -2308,49 +4564,31 @@ gdk_window_draw_pixbuf (GdkDrawable *drawable, gint y_dither) { GdkWindowObject *private = (GdkWindowObject *)drawable; + GdkDrawableClass *klass; if (GDK_WINDOW_DESTROYED (drawable)) return; - - if (gc) - { - OFFSET_GC (gc); - - if (private->paint_stack) - { - GdkWindowPaint *paint = private->paint_stack->data; - gdk_draw_pixbuf (paint->pixmap, gc, pixbuf, src_x, src_y, - dest_x - x_offset, dest_y - y_offset, - width, height, - dither, x_dither - x_offset, y_dither - y_offset); - } - else - gdk_draw_pixbuf (private->impl, gc, pixbuf, src_x, src_y, - dest_x - x_offset, dest_y - y_offset, - width, height, - dither, x_dither, y_dither); - - RESTORE_GC (gc); - } + + /* If no gc => no user clipping, but we need clipping + for window emulation, so use a scratch gc */ + if (!gc) + gc = _gdk_drawable_get_scratch_gc (drawable, FALSE); + + BEGIN_DRAW; + + klass = GDK_DRAWABLE_GET_CLASS (impl); + + if (private->paint_stack) + klass->draw_pixbuf (impl, gc, pixbuf, src_x, src_y, + dest_x - x_offset, dest_y - y_offset, + width, height, + dither, x_dither - x_offset, y_dither - y_offset); else - { - gint x_offset, y_offset; - gdk_window_get_offsets (drawable, &x_offset, &y_offset); - - if (private->paint_stack) - { - GdkWindowPaint *paint = private->paint_stack->data; - gdk_draw_pixbuf (paint->pixmap, gc, pixbuf, src_x, src_y, - dest_x - x_offset, dest_y - y_offset, - width, height, - dither, x_dither - x_offset, y_dither - y_offset); - } - else - gdk_draw_pixbuf (private->impl, gc, pixbuf, src_x, src_y, - dest_x - x_offset, dest_y - y_offset, - width, height, - dither, x_dither, y_dither); - } + klass->draw_pixbuf (impl, gc, pixbuf, src_x, src_y, + dest_x - x_offset, dest_y - y_offset, + width, height, + dither, x_dither, y_dither); + END_DRAW; } static void @@ -2359,14 +4597,13 @@ gdk_window_draw_trapezoids (GdkDrawable *drawable, GdkTrapezoid *trapezoids, gint n_trapezoids) { - GdkWindowObject *private = (GdkWindowObject *)drawable; GdkTrapezoid *new_trapezoids = NULL; - OFFSET_GC (gc); - if (GDK_WINDOW_DESTROYED (drawable)) return; - + + BEGIN_DRAW; + if (x_offset != 0 || y_offset != 0) { gint i; @@ -2385,28 +4622,24 @@ gdk_window_draw_trapezoids (GdkDrawable *drawable, trapezoids = new_trapezoids; } - if (private->paint_stack) - { - GdkWindowPaint *paint = private->paint_stack->data; - gdk_draw_trapezoids (paint->pixmap, gc, trapezoids, n_trapezoids); - } - else - gdk_draw_trapezoids (private->impl, gc, trapezoids, n_trapezoids); - + gdk_draw_trapezoids (impl, gc, trapezoids, n_trapezoids); + g_free (new_trapezoids); - RESTORE_GC (gc); + END_DRAW; } static void gdk_window_real_get_size (GdkDrawable *drawable, - gint *width, - gint *height) + gint *width, + gint *height) { - g_return_if_fail (GDK_IS_WINDOW (drawable)); + GdkWindowObject *private = (GdkWindowObject *)drawable; - gdk_drawable_get_size (GDK_WINDOW_OBJECT (drawable)->impl, - width, height); + if (width) + *width = private->width; + if (height) + *height = private->height; } static GdkVisual* @@ -2436,14 +4669,23 @@ gdk_window_real_get_screen (GdkDrawable *drawable) static void gdk_window_real_set_colormap (GdkDrawable *drawable, - GdkColormap *cmap) + GdkColormap *cmap) { - g_return_if_fail (GDK_IS_WINDOW (drawable)); + GdkWindowObject *private; + + g_return_if_fail (GDK_IS_WINDOW (drawable)); if (GDK_WINDOW_DESTROYED (drawable)) return; - - gdk_drawable_set_colormap (((GdkWindowObject*)drawable)->impl, cmap); + + private = (GdkWindowObject *)drawable; + + /* different colormap than parent, requires native window */ + if (!private->input_only && + cmap != gdk_drawable_get_colormap ((GdkDrawable *)(private->parent))) + gdk_window_ensure_native ((GdkWindow *)drawable); + + gdk_drawable_set_colormap (private->impl, cmap); } static GdkColormap* @@ -2453,10 +4695,10 @@ gdk_window_real_get_colormap (GdkDrawable *drawable) if (GDK_WINDOW_DESTROYED (drawable)) return NULL; - + return gdk_drawable_get_colormap (((GdkWindowObject*)drawable)->impl); } - + static GdkImage* gdk_window_copy_to_image (GdkDrawable *drawable, GdkImage *image, @@ -2469,19 +4711,20 @@ gdk_window_copy_to_image (GdkDrawable *drawable, { GdkWindowObject *private = (GdkWindowObject *) drawable; gint x_offset, y_offset; - + g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL); - + if (GDK_WINDOW_DESTROYED (drawable)) return NULL; /* If we're here, a composite image was not necessary, so * we can ignore the paint stack. */ - - GDK_WINDOW_IMPL_GET_IFACE (private->impl)->get_offsets (drawable, - &x_offset, &y_offset); - + + /* TODO: Is this right? */ + x_offset = 0; + y_offset = 0; + return gdk_drawable_copy_to_image (private->impl, image, src_x - x_offset, @@ -2490,6 +4733,24 @@ gdk_window_copy_to_image (GdkDrawable *drawable, width, height); } +static void +gdk_window_cairo_surface_destroy (void *data) +{ + GdkWindowObject *private = (GdkWindowObject*) data; + + private->cairo_surface = NULL; +} + +static cairo_surface_t * +gdk_window_create_cairo_surface (GdkDrawable *drawable, + int width, + int height) +{ + return _gdk_windowing_create_cairo_surface (GDK_WINDOW_OBJECT(drawable)->impl, + width, height); +} + + static cairo_surface_t * gdk_window_ref_cairo_surface (GdkDrawable *drawable) { @@ -2504,22 +4765,192 @@ gdk_window_ref_cairo_surface (GdkDrawable *drawable) cairo_surface_reference (surface); } else - surface = _gdk_drawable_ref_cairo_surface (private->impl); + { + + /* This will be drawing directly to the window, so flush implicit paint */ + gdk_window_flush ((GdkWindow *)drawable); + + if (!private->cairo_surface) + { + int width, height; + GdkDrawable *source; + + /* It would be nice if we had some cairo support here so we + could set the clip rect on the cairo surface */ + width = private->abs_x + private->width; + height = private->abs_y + private->height; + + source = _gdk_drawable_get_source_drawable (drawable); + + /* TODO: Avoid the typecheck crap by adding virtual call */ + private->cairo_surface = _gdk_drawable_create_cairo_surface (source, width, height); + + if (private->cairo_surface) + { + cairo_surface_set_device_offset (private->cairo_surface, + private->abs_x, + private->abs_y); + + cairo_surface_set_user_data (private->cairo_surface, &gdk_window_cairo_key, + drawable, gdk_window_cairo_surface_destroy); + } + } + else + cairo_surface_reference (private->cairo_surface); + + surface = private->cairo_surface; + } return surface; } +static void +gdk_window_set_cairo_clip (GdkDrawable *drawable, + cairo_t *cr) +{ + GdkWindowObject *private = (GdkWindowObject*) drawable; + + if (!private->paint_stack) + { + cairo_reset_clip (cr); + + cairo_save (cr); + cairo_identity_matrix (cr); + + cairo_new_path (cr); + gdk_cairo_region (cr, private->clip_region_with_children); + + cairo_restore (cr); + cairo_clip (cr); + } + else + { + GdkWindowPaint *paint = private->paint_stack->data; + + /* Only needs to clip to region if piggybacking + on an implicit paint pixmap */ + cairo_reset_clip (cr); + if (paint->uses_implicit) + { + cairo_save (cr); + cairo_identity_matrix (cr); + + cairo_new_path (cr); + gdk_cairo_region (cr, paint->region); + cairo_restore (cr); + + cairo_clip (cr); + } + } +} + /* Code for dirty-region queueing */ static GSList *update_windows = NULL; static guint update_idle = 0; static gboolean debug_updates = FALSE; +static inline gboolean +gdk_window_is_ancestor (GdkWindow *window, + GdkWindow *ancestor) +{ + while (window) + { + GdkWindow *parent = (GdkWindow*) ((GdkWindowObject*) window)->parent; + + if (parent == ancestor) + return TRUE; + + window = parent; + } + + return FALSE; +} + +static void +gdk_window_add_update_window (GdkWindow *window) +{ + GSList *tmp; + GSList *prev = NULL; + gboolean has_ancestor_in_list = FALSE; + + for (tmp = update_windows; tmp; tmp = tmp->next) + { + GdkWindowObject *parent = GDK_WINDOW_OBJECT (window)->parent; + + /* check if tmp is an ancestor of "window"; if it is, set a + * flag indicating that all following windows are either + * children of "window" or from a differen hierarchy + */ + if (!has_ancestor_in_list && gdk_window_is_ancestor (window, tmp->data)) + has_ancestor_in_list = TRUE; + + /* insert in reverse stacking order when adding around siblings, + * so processing updates properly paints over lower stacked windows + */ + if (parent == GDK_WINDOW_OBJECT (tmp->data)->parent) + { + gint index = g_list_index (parent->children, window); + for (; tmp && parent == GDK_WINDOW_OBJECT (tmp->data)->parent; tmp = tmp->next) + { + gint sibling_index = g_list_index (parent->children, tmp->data); + if (index > sibling_index) + break; + prev = tmp; + } + /* here, tmp got advanced past all lower stacked siblings */ + tmp = g_slist_prepend (tmp, window); + if (prev) + prev->next = tmp; + else + update_windows = tmp; + return; + } + + /* if "window" has an ancestor in the list and tmp is one of + * "window's" children, insert "window" before tmp + */ + if (has_ancestor_in_list && gdk_window_is_ancestor (tmp->data, window)) + { + tmp = g_slist_prepend (tmp, window); + + if (prev) + prev->next = tmp; + else + update_windows = tmp; + return; + } + + /* if we're at the end of the list and had an ancestor it it, + * append to the list + */ + if (! tmp->next && has_ancestor_in_list) + { + tmp = g_slist_append (tmp, window); + return; + } + + prev = tmp; + } + + /* if all above checks failed ("window" is from a different + * hierarchy than what is already in the list) or the list is + * empty, prepend + */ + update_windows = g_slist_prepend (update_windows, window); +} + +static void +gdk_window_remove_update_window (GdkWindow *window) +{ + update_windows = g_slist_remove (update_windows, window); +} + static gboolean gdk_window_update_idle (gpointer data) { gdk_window_process_all_updates (); - + return FALSE; } @@ -2542,17 +4973,131 @@ gdk_window_schedule_update (GdkWindow *window) return; if (!update_idle) + update_idle = + gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW, + gdk_window_update_idle, + NULL, NULL); +} + +void +_gdk_window_process_updates_recurse (GdkWindow *window, + GdkRegion *expose_region) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowObject *child; + GdkRegion *child_region; + GdkRectangle r; + GList *l, *children; + + if (gdk_region_empty (expose_region)) + return; + + /* Make this reentrancy safe for expose handlers freeing windows */ + children = g_list_copy (private->children); + g_list_foreach (children, (GFunc)g_object_ref, NULL); + + /* Iterate over children, starting at topmost */ + for (l = children; l != NULL; l = l->next) { - update_idle = gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW, - gdk_window_update_idle, NULL, NULL); + child = l->data; + + if (child->destroyed || !GDK_WINDOW_IS_MAPPED (child) || child->input_only || child->composited) + continue; + + /* Ignore offscreen children, as they don't draw in their parent and + * don't take part in the clipping */ + if (gdk_window_is_offscreen (child)) + continue; + + r.x = child->x; + r.y = child->y; + r.width = child->width; + r.height = child->height; + + child_region = gdk_region_rectangle (&r); + if (child->shape) + { + /* Adjust shape region to parent window coords */ + gdk_region_offset (child->shape, child->x, child->y); + gdk_region_intersect (child_region, child->shape); + gdk_region_offset (child->shape, -child->x, -child->y); + } + + if (child->impl == private->impl) + { + /* Client side child, expose */ + gdk_region_intersect (child_region, expose_region); + gdk_region_subtract (expose_region, child_region); + gdk_region_offset (child_region, -child->x, -child->y); + _gdk_window_process_updates_recurse ((GdkWindow *)child, child_region); + } + else + { + /* Native child, just remove area from expose region */ + gdk_region_subtract (expose_region, child_region); + } + gdk_region_destroy (child_region); + } + + g_list_foreach (children, (GFunc)g_object_unref, NULL); + g_list_free (children); + + if (!gdk_region_empty (expose_region) && + !private->destroyed) + { + if (private->event_mask & GDK_EXPOSURE_MASK) + { + GdkEvent event; + + event.expose.type = GDK_EXPOSE; + event.expose.window = g_object_ref (window); + event.expose.send_event = FALSE; + event.expose.count = 0; + event.expose.region = expose_region; + gdk_region_get_clipbox (expose_region, &event.expose.area); + + (*_gdk_event_func) (&event, _gdk_event_data); + + g_object_unref (window); + } + else if (private->bg_pixmap != GDK_NO_BG && + private->window_type != GDK_WINDOW_FOREIGN) + { + /* No exposure mask set, so nothing will be drawn, the + * app relies on the background being what it specified + * for the window. So, we need to clear this manually. + * + * For foreign windows if expose is not set that generally + * means some other client paints them, so don't clear + * there. + * + * We use begin/end_paint around the clear so that we can + * piggyback on the implicit paint */ + + gdk_window_begin_paint_region (window, expose_region); + gdk_window_clear_region_internal (window, expose_region, FALSE); + gdk_window_end_paint (window); + } } } +/* Process and remove any invalid area on the native window by creating + * expose events for the window and all non-native descendants. + * Also processes any outstanding moves on the window before doing + * any drawing. Note that its possible to have outstanding moves without + * any invalid area as we use the update idle mechanism to coalesce + * multiple moves as well as multiple invalidations. + */ static void gdk_window_process_updates_internal (GdkWindow *window) { GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowImplIface *impl_iface; gboolean save_region = FALSE; + GdkRectangle clip_box; + + /* Ensure the window lives while updating it */ + g_object_ref (window); /* If an update got queued during update processing, we can get a * window in the update queue that has an empty update_area. @@ -2562,63 +5107,151 @@ gdk_window_process_updates_internal (GdkWindow *window) { GdkRegion *update_area = private->update_area; private->update_area = NULL; - + if (_gdk_event_func && gdk_window_is_viewable (window)) { - GdkRectangle window_rect; GdkRegion *expose_region; - GdkRegion *window_region; - gint width, height; + gboolean end_implicit; - if (debug_updates) - { - /* Make sure we see the red invalid area before redrawing. */ - gdk_display_sync (gdk_drawable_get_display (window)); - g_usleep (70000); - } - - save_region = _gdk_windowing_window_queue_antiexpose (window, update_area); + /* Clip to part visible in toplevel */ + gdk_region_intersect (update_area, private->clip_region); - if (save_region) - expose_region = gdk_region_copy (update_area); - else - expose_region = update_area; - - gdk_drawable_get_size (GDK_DRAWABLE (private), &width, &height); - - window_rect.x = 0; - window_rect.y = 0; - window_rect.width = width; - window_rect.height = height; - - window_region = gdk_region_rectangle (&window_rect); - gdk_region_intersect (expose_region, - window_region); - gdk_region_destroy (window_region); - - if (!gdk_region_empty (expose_region) && - (private->event_mask & GDK_EXPOSURE_MASK)) + if (debug_updates) { - GdkEvent event; - - event.expose.type = GDK_EXPOSE; - event.expose.window = g_object_ref (window); - event.expose.send_event = FALSE; - event.expose.count = 0; - event.expose.region = expose_region; - gdk_region_get_clipbox (expose_region, &event.expose.area); - - (*_gdk_event_func) (&event, _gdk_event_data); - - g_object_unref (window); + /* Make sure we see the red invalid area before redrawing. */ + gdk_display_sync (gdk_drawable_get_display (window)); + g_usleep (70000); } - if (expose_region != update_area) - gdk_region_destroy (expose_region); + /* At this point we will be completely redrawing all of update_area. + * If we have any outstanding moves that end up moving stuff inside + * this area we don't actually need to move that as that part would + * be overdrawn by the expose anyway. So, in order to copy less data + * we remove these areas from the outstanding moves. + */ + if (private->outstanding_moves) + { + GdkWindowRegionMove *move; + GdkRegion *remove; + GList *l, *prev; + + remove = gdk_region_copy (update_area); + /* We iterate backwards, starting from the state that would be + if we had applied all the moves. */ + for (l = g_list_last (private->outstanding_moves); l != NULL; l = prev) + { + prev = l->prev; + move = l->data; + + /* Don't need this area */ + gdk_region_subtract (move->dest_region, remove); + + /* However if any of the destination we do need has a source + in the updated region we do need that as a destination for + the earlier moves */ + gdk_region_offset (move->dest_region, -move->dx, -move->dy); + gdk_region_subtract (remove, move->dest_region); + + if (gdk_region_empty (move->dest_region)) + { + gdk_window_region_move_free (move); + private->outstanding_moves = + g_list_delete_link (private->outstanding_moves, l); + } + else /* move back */ + gdk_region_offset (move->dest_region, move->dx, move->dy); + } + gdk_region_destroy (remove); + } + + /* By now we a set of window moves that should be applied, and then + * an update region that should be repainted. A trivial implementation + * would just do that in order, however in order to get nicer drawing + * we do some tricks: + * + * First of all, each subwindow expose may be double buffered by + * itself (depending on widget setting) via + * gdk_window_begin/end_paint(). But we also do an "implicit" paint, + * creating a single pixmap the size of the invalid area on the + * native window which all the individual normal paints will draw + * into. This way in the normal case there will be only one pixmap + * allocated and only once pixmap draw done for all the windows + * in this native window. + * There are a couple of reasons this may fail, for instance, some + * backends (like quartz) do its own double buffering, so we disable + * gdk double buffering there. Secondly, some subwindow could be + * non-double buffered and draw directly to the window outside a + * begin/end_paint pair. That will be lead to a gdk_window_flush + * which immediately executes all outstanding moves and paints+removes + * the implicit paint (further paints will allocate their own pixmap). + * + * Secondly, in the case of implicit double buffering we expose all + * the child windows into the implicit pixmap before we execute + * the outstanding moves. This way we minimize the time between + * doing the moves and rendering the new update area, thus minimizing + * flashing. Of course, if any subwindow is non-double buffered we + * well flush earlier than that. + * + * Thirdly, after having done the outstanding moves we queue an + * "antiexpose" on the area that will be drawn by the expose, which + * means that any invalid region on the native window side before + * the first expose drawing operation will be discarded, as it + * has by then been overdrawn with valid data. This means we can + * avoid doing the unnecessary repaint any outstanding expose events. + */ + + gdk_region_get_clipbox (update_area, &clip_box); + end_implicit = gdk_window_begin_implicit_paint (window, &clip_box); + expose_region = gdk_region_copy (update_area); + if (!end_implicit) + { + /* Rendering is not double buffered by gdk, do outstanding + * moves and queue antiexposure immediately. No need to do + * any tricks */ + gdk_window_flush_outstanding_moves (window); + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + save_region = impl_iface->queue_antiexpose (window, update_area); + } + + /* Render the invalid areas to the implicit paint, by sending exposes. + * May flush if non-double buffered widget draw. */ + _gdk_windowing_window_process_updates_recurse (window, expose_region); + + if (end_implicit) + { + /* Do moves right before exposes are rendered to the window */ + gdk_window_flush_outstanding_moves (window); + + /* By this time we know that any outstanding expose for this + * area is invalid and we can avoid it, so queue an antiexpose. + * However, it may be that due to an non-double buffered expose + * we have already started drawing to the window, so it would + * be to late to anti-expose now. Since this is merely an + * optimization we just avoid doing it at all in that case. + */ + if (private->implicit_paint != NULL && + !private->implicit_paint->flushed) + { + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + save_region = impl_iface->queue_antiexpose (window, update_area); + } + + gdk_window_end_implicit_paint (window); + } + gdk_region_destroy (expose_region); } if (!save_region) gdk_region_destroy (update_area); } + + if (private->outstanding_moves) + { + /* Flush any outstanding moves, may happen if we moved a window but got + no actual invalid area */ + gdk_window_flush_outstanding_moves (window); + } + + g_object_unref (window); } static void @@ -2648,31 +5281,47 @@ flush_all_displays (void) * * Calls gdk_window_process_updates() for all windows (see #GdkWindow) * in the application. - * + * **/ void gdk_window_process_all_updates (void) { GSList *old_update_windows = update_windows; GSList *tmp_list = update_windows; + static gboolean in_process_all_updates = FALSE; + static gboolean got_recursive_update = FALSE; + + if (in_process_all_updates) + { + /* We can't do this now since that would recurse, so + delay it until after the recursion is done. */ + got_recursive_update = TRUE; + update_idle = 0; + return; + } + + in_process_all_updates = TRUE; + got_recursive_update = FALSE; if (update_idle) g_source_remove (update_idle); - + update_windows = NULL; update_idle = 0; + _gdk_windowing_before_process_all_updates (); + g_slist_foreach (old_update_windows, (GFunc)g_object_ref, NULL); - + while (tmp_list) { GdkWindowObject *private = (GdkWindowObject *)tmp_list->data; - + if (!GDK_WINDOW_DESTROYED (tmp_list->data)) - { + { if (private->update_freeze_count || gdk_window_is_toplevel_frozen (tmp_list->data)) - update_windows = g_slist_prepend (update_windows, private); + gdk_window_add_update_window ((GdkWindow *) private); else gdk_window_process_updates_internal (tmp_list->data); } @@ -2684,6 +5333,20 @@ gdk_window_process_all_updates (void) g_slist_free (old_update_windows); flush_all_displays (); + + _gdk_windowing_after_process_all_updates (); + + in_process_all_updates = FALSE; + + /* If we ignored a recursive call, schedule a + redraw now so that it eventually happens, + otherwise we could miss an update if nothing + else schedules an update. */ + if (got_recursive_update && !update_idle) + update_idle = + gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW, + gdk_window_update_idle, + NULL, NULL); } /** @@ -2691,7 +5354,7 @@ gdk_window_process_all_updates (void) * @window: a #GdkWindow * @update_children: whether to also process updates for child windows * - * Sends one or more expose events to @window. The areas in each + * Sends one or more expose events to @window. The areas in each * expose event will cover the entire update area for the window (see * gdk_window_invalidate_region() for details). Normally GDK calls * gdk_window_process_all_updates() on your behalf, so there's no @@ -2699,43 +5362,57 @@ gdk_window_process_all_updates (void) * to be delivered immediately and synchronously (vs. the usual * case, where GDK delivers them in an idle handler). Occasionally * this is useful to produce nicer scrolling behavior, for example. - * + * **/ void gdk_window_process_updates (GdkWindow *window, gboolean update_children) { GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowObject *impl_window; g_return_if_fail (GDK_IS_WINDOW (window)); - if (GDK_IS_PAINTABLE (private->impl)) + if (GDK_WINDOW_DESTROYED (window)) + return; + + /* Make sure the window lives during the expose callouts */ + g_object_ref (window); + + impl_window = gdk_window_get_impl_window (private); + if ((impl_window->update_area || + impl_window->outstanding_moves) && + !impl_window->update_freeze_count && + !gdk_window_is_toplevel_frozen (window) && + + /* Don't recurse into process_updates_internal, we'll + * do the update later when idle instead. */ + impl_window->implicit_paint == NULL) { - GdkPaintableIface *iface = GDK_PAINTABLE_GET_IFACE (private->impl); - - if (iface->process_updates) - iface->process_updates ((GdkPaintable*)private->impl, update_children); - - return; - } - - if (private->update_area && - !private->update_freeze_count && - !gdk_window_is_toplevel_frozen (window)) - { - gdk_window_process_updates_internal (window); - update_windows = g_slist_remove (update_windows, window); + gdk_window_process_updates_internal ((GdkWindow *)impl_window); + gdk_window_remove_update_window ((GdkWindow *)impl_window); } if (update_children) { - GList *tmp_list = private->children; - while (tmp_list) + /* process updates in reverse stacking order so composition or + * painting over achieves the desired effect for offscreen windows + */ + GList *node, *children; + + children = g_list_copy (private->children); + g_list_foreach (children, (GFunc)g_object_ref, NULL); + + for (node = g_list_last (children); node; node = node->prev) { - gdk_window_process_updates (tmp_list->data, TRUE); - tmp_list = tmp_list->next; + gdk_window_process_updates (node->data, TRUE); + g_object_unref (node->data); } + + g_list_free (children); } + + g_object_unref (window); } /** @@ -2751,8 +5428,8 @@ gdk_window_process_updates (GdkWindow *window, **/ void gdk_window_invalidate_rect (GdkWindow *window, - const GdkRectangle *rect, - gboolean invalidate_children) + const GdkRectangle *rect, + gboolean invalidate_children) { GdkRectangle window_rect; GdkRegion *region; @@ -2762,8 +5439,8 @@ gdk_window_invalidate_rect (GdkWindow *window, if (GDK_WINDOW_DESTROYED (window)) return; - - if (private->input_only || !GDK_WINDOW_IS_MAPPED (window)) + + if (private->input_only || !private->viewable) return; if (!rect) @@ -2771,8 +5448,8 @@ gdk_window_invalidate_rect (GdkWindow *window, window_rect.x = 0; window_rect.y = 0; gdk_drawable_get_size (GDK_DRAWABLE (window), - &window_rect.width, - &window_rect.height); + &window_rect.width, + &window_rect.height); rect = &window_rect; } @@ -2783,28 +5460,42 @@ gdk_window_invalidate_rect (GdkWindow *window, static void draw_ugly_color (GdkWindow *window, - const GdkRegion *region) + const GdkRegion *region) { /* Draw ugly color all over the newly-invalid region */ GdkColor ugly_color = { 0, 50000, 10000, 10000 }; GdkGC *ugly_gc; GdkRectangle clipbox; - + ugly_gc = gdk_gc_new (window); gdk_gc_set_rgb_fg_color (ugly_gc, &ugly_color); gdk_gc_set_clip_region (ugly_gc, region); gdk_region_get_clipbox (region, &clipbox); - + gdk_draw_rectangle (window, ugly_gc, TRUE, clipbox.x, clipbox.y, clipbox.width, clipbox.height); - + g_object_unref (ugly_gc); } +static void +impl_window_add_update_area (GdkWindowObject *impl_window, + GdkRegion *region) +{ + if (impl_window->update_area) + gdk_region_union (impl_window->update_area, region); + else + { + gdk_window_add_update_window ((GdkWindow *)impl_window); + impl_window->update_area = gdk_region_copy (region); + gdk_window_schedule_update ((GdkWindow *)impl_window); + } +} + /** * gdk_window_invalidate_maybe_recurse: * @window: a #GdkWindow @@ -2832,12 +5523,13 @@ draw_ugly_color (GdkWindow *window, **/ void gdk_window_invalidate_maybe_recurse (GdkWindow *window, - const GdkRegion *region, - gboolean (*child_func) (GdkWindow *, - gpointer), + const GdkRegion *region, + gboolean (*child_func) (GdkWindow *, + gpointer), gpointer user_data) { GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowObject *impl_window; GdkRegion *visible_region; GList *tmp_list; @@ -2845,67 +5537,49 @@ gdk_window_invalidate_maybe_recurse (GdkWindow *window, if (GDK_WINDOW_DESTROYED (window)) return; - - if (private->input_only || !GDK_WINDOW_IS_MAPPED (window)) + + if (private->input_only || + !private->viewable || + gdk_region_empty (region) || + private->window_type == GDK_WINDOW_ROOT) return; - if (GDK_IS_PAINTABLE (private->impl)) - { - GdkPaintableIface *iface = GDK_PAINTABLE_GET_IFACE (private->impl); - - if (iface->invalidate_maybe_recurse) - iface->invalidate_maybe_recurse ((GdkPaintable*)private->impl, - region, child_func, user_data); - return; - } - - /* windows that a redirection has ben setup for need to be considered - * fully visible, in order to avoid missing redirected paint ops - * anywhere in the window area. - */ - if (private->redirect && private->redirect->redirected == private) - { - GdkRectangle visible_rect = { 0, 0, 0, 0 }; - gdk_drawable_get_size (GDK_DRAWABLE (window), &visible_rect.width, &visible_rect.height); - visible_region = gdk_region_rectangle (&visible_rect); - } - else - visible_region = gdk_drawable_get_visible_region (window); + visible_region = gdk_drawable_get_visible_region (window); gdk_region_intersect (visible_region, region); tmp_list = private->children; while (tmp_list) { GdkWindowObject *child = tmp_list->data; - + if (!child->input_only) { GdkRegion *child_region; GdkRectangle child_rect; - - gdk_window_get_position ((GdkWindow *)child, - &child_rect.x, &child_rect.y); - gdk_drawable_get_size ((GdkDrawable *)child, - &child_rect.width, &child_rect.height); + child_rect.x = child->x; + child_rect.y = child->y; + child_rect.width = child->width; + child_rect.height = child->height; child_region = gdk_region_rectangle (&child_rect); - + /* remove child area from the invalid area of the parent */ if (GDK_WINDOW_IS_MAPPED (child) && !child->shaped && - !child->composited) + !child->composited && + !gdk_window_is_offscreen (child)) gdk_region_subtract (visible_region, child_region); - + if (child_func && (*child_func) ((GdkWindow *)child, user_data)) { - GdkRegion *tmp = gdk_region_copy (region); + GdkRegion *tmp = gdk_region_copy (region); gdk_region_offset (tmp, - child_rect.x, - child_rect.y); gdk_region_offset (child_region, - child_rect.x, - child_rect.y); gdk_region_intersect (child_region, tmp); - + gdk_window_invalidate_maybe_recurse ((GdkWindow *)child, child_region, child_func, user_data); - + gdk_region_destroy (tmp); } @@ -2914,25 +5588,23 @@ gdk_window_invalidate_maybe_recurse (GdkWindow *window, tmp_list = tmp_list->next; } - - if (!gdk_region_empty (visible_region)) + + impl_window = gdk_window_get_impl_window (private); + + if (!gdk_region_empty (visible_region) || + /* Even if we're not exposing anything, make sure we process + idles for windows with outstanding moves */ + (impl_window->outstanding_moves != NULL && + impl_window->update_area == NULL)) { if (debug_updates) - draw_ugly_color (window, region); + draw_ugly_color (window, region); - if (private->update_area) - { - gdk_region_union (private->update_area, visible_region); - } - else - { - update_windows = g_slist_prepend (update_windows, window); - private->update_area = gdk_region_copy (visible_region); - - gdk_window_schedule_update (window); - } + /* Convert to impl coords */ + gdk_region_offset (visible_region, private->abs_x, private->abs_y); + impl_window_add_update_area (impl_window, visible_region); } - + gdk_region_destroy (visible_region); } @@ -2947,7 +5619,7 @@ true_predicate (GdkWindow *window, * gdk_window_invalidate_region: * @window: a #GdkWindow * @region: a #GdkRegion - * @invalidate_children: %TRUE to also invalidate child windows + * @invalidate_children: %TRUE to also invalidate child windows * * Adds @region to the update area for @window. The update area is the * region that needs to be redrawn, or "dirty region." The call @@ -2974,39 +5646,125 @@ gdk_window_invalidate_region (GdkWindow *window, { gdk_window_invalidate_maybe_recurse (window, region, invalidate_children ? - true_predicate : (gboolean (*) (GdkWindow *, gpointer))NULL, + true_predicate : (gboolean (*) (GdkWindow *, gpointer))NULL, NULL); } +/** + * _gdk_window_invalidate_for_expose: + * @window: a #GdkWindow + * @region: a #GdkRegion + * + * Adds @region to the update area for @window. The update area is the + * region that needs to be redrawn, or "dirty region." The call + * gdk_window_process_updates() sends one or more expose events to the + * window, which together cover the entire update area. An + * application would normally redraw the contents of @window in + * response to those expose events. + * + * GDK will call gdk_window_process_all_updates() on your behalf + * whenever your program returns to the main loop and becomes idle, so + * normally there's no need to do that manually, you just need to + * invalidate regions that you know should be redrawn. + * + * This version of invalidation is used when you recieve expose events + * from the native window system. It exposes the native window, plus + * any non-native child windows (but not native child windows, as those would + * have gotten their own expose events). + **/ +void +_gdk_window_invalidate_for_expose (GdkWindow *window, + GdkRegion *region) +{ + GdkWindowObject *private = (GdkWindowObject *) window; + GdkWindowRegionMove *move; + GdkRegion *move_region; + GList *l; + + /* Any invalidations comming from the windowing system will + be in areas that may be moved by outstanding moves, + so we need to modify the expose region correspondingly, + otherwise we would expose in the wrong place, as the + outstanding moves will be copied before we draw the + exposes. */ + for (l = private->outstanding_moves; l != NULL; l = l->next) + { + move = l->data; + + /* covert to move source region */ + move_region = gdk_region_copy (move->dest_region); + gdk_region_offset (move_region, -move->dx, -move->dy); + + /* Move area of region that intersects with move source + by dx, dy of the move*/ + gdk_region_intersect (move_region, region); + gdk_region_subtract (region, move_region); + gdk_region_offset (move_region, move->dx, move->dy); + gdk_region_union (region, move_region); + + gdk_region_destroy (move_region); + } + + gdk_window_invalidate_maybe_recurse (window, region, + (gboolean (*) (GdkWindow *, gpointer))gdk_window_has_no_impl, + NULL); +} + + /** * gdk_window_get_update_area: * @window: a #GdkWindow - * + * * Transfers ownership of the update area from @window to the caller * of the function. That is, after calling this function, @window will * no longer have an invalid/dirty region; the update area is removed * from @window and handed to you. If a window has no update area, * gdk_window_get_update_area() returns %NULL. You are responsible for * calling gdk_region_destroy() on the returned region if it's non-%NULL. - * + * * Return value: the update area for @window **/ GdkRegion * gdk_window_get_update_area (GdkWindow *window) { GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowObject *impl_window; GdkRegion *tmp_region; g_return_val_if_fail (GDK_IS_WINDOW (window), NULL); - if (private->update_area) - { - tmp_region = private->update_area; - private->update_area = NULL; + impl_window = gdk_window_get_impl_window (private); - update_windows = g_slist_remove (update_windows, window); - - return tmp_region; + if (impl_window->update_area) + { + tmp_region = gdk_region_copy (private->clip_region_with_children); + /* Convert to impl coords */ + gdk_region_offset (tmp_region, private->abs_x, private->abs_y); + gdk_region_intersect (tmp_region, impl_window->update_area); + + if (gdk_region_empty (tmp_region)) + { + gdk_region_destroy (tmp_region); + return NULL; + } + else + { + gdk_region_subtract (impl_window->update_area, tmp_region); + + if (gdk_region_empty (impl_window->update_area) && + impl_window->outstanding_moves == NULL) + { + gdk_region_destroy (impl_window->update_area); + impl_window->update_area = NULL; + + gdk_window_remove_update_window ((GdkWindow *)impl_window); + } + + /* Convert from impl coords */ + gdk_region_offset (tmp_region, -private->abs_x, -private->abs_y); + return tmp_region; + + } } else return NULL; @@ -3015,7 +5773,7 @@ gdk_window_get_update_area (GdkWindow *window) /** * _gdk_window_clear_update_area: * @window: a #GdkWindow. - * + * * Internal function to clear the update area for a window. This * is called when the window is hidden or destroyed. **/ @@ -3028,8 +5786,8 @@ _gdk_window_clear_update_area (GdkWindow *window) if (private->update_area) { - update_windows = g_slist_remove (update_windows, window); - + gdk_window_remove_update_window (window); + gdk_region_destroy (private->update_area); private->update_area = NULL; } @@ -3038,7 +5796,7 @@ _gdk_window_clear_update_area (GdkWindow *window) /** * gdk_window_freeze_updates: * @window: a #GdkWindow - * + * * Temporarily freezes a window such that it won't receive expose * events. The window will begin receiving expose events again when * gdk_window_thaw_updates() is called. If gdk_window_freeze_updates() @@ -3049,28 +5807,34 @@ void gdk_window_freeze_updates (GdkWindow *window) { GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowObject *impl_window; g_return_if_fail (GDK_IS_WINDOW (window)); - private->update_freeze_count++; + impl_window = gdk_window_get_impl_window (private); + impl_window->update_freeze_count++; } /** * gdk_window_thaw_updates: * @window: a #GdkWindow - * + * * Thaws a window frozen with gdk_window_freeze_updates(). **/ void gdk_window_thaw_updates (GdkWindow *window) { GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowObject *impl_window; g_return_if_fail (GDK_IS_WINDOW (window)); - g_return_if_fail (private->update_freeze_count > 0); - if (--private->update_freeze_count == 0) - gdk_window_schedule_update (window); + impl_window = gdk_window_get_impl_window (private); + + g_return_if_fail (impl_window->update_freeze_count > 0); + + if (--impl_window->update_freeze_count == 0) + gdk_window_schedule_update (GDK_WINDOW (impl_window)); } /** @@ -3102,7 +5866,7 @@ gdk_window_freeze_toplevel_updates_libgtk_only (GdkWindow *window) /** * gdk_window_thaw_toplevel_updates_libgtk_only: * @window: a #GdkWindow - * + * * Thaws a window frozen with * gdk_window_freeze_toplevel_updates_libgtk_only(). * @@ -3146,7 +5910,7 @@ gdk_window_thaw_toplevel_updates_libgtk_only (GdkWindow *window) * usually more useful than calling gdk_window_set_debug_updates() * yourself, though you might want to use this function to enable * updates sometime after application startup time. - * + * **/ void gdk_window_set_debug_updates (gboolean setting) @@ -3162,8 +5926,8 @@ gdk_window_set_debug_updates (gboolean setting) * @height: desired height of the window * @new_width: location to store resulting width * @new_height: location to store resulting height - * - * Constrains a desired width and height according to a + * + * Constrains a desired width and height according to a * set of geometry hints (such as minimum and maximum size). */ void @@ -3190,7 +5954,7 @@ gdk_window_constrain_size (GdkGeometry *geometry, gint yinc = 1; gint max_width = G_MAXINT; gint max_height = G_MAXINT; - + #define FLOOR(value, base) ( ((gint) ((value) / (base))) * (base) ) if ((flags & GDK_HINT_BASE_SIZE) && (flags & GDK_HINT_MIN_SIZE)) @@ -3226,12 +5990,12 @@ gdk_window_constrain_size (GdkGeometry *geometry, xinc = MAX (xinc, geometry->width_inc); yinc = MAX (yinc, geometry->height_inc); } - + /* clamp width and height to min and max values */ width = CLAMP (width, min_width, max_width); height = CLAMP (height, min_height, max_height); - + /* shrink to base + N * inc */ width = base_width + FLOOR (width - base_width, xinc); @@ -3239,11 +6003,11 @@ gdk_window_constrain_size (GdkGeometry *geometry, /* constrain aspect ratio, according to: * - * width + * width * min_aspect <= -------- <= max_aspect - * height + * height */ - + if (flags & GDK_HINT_ASPECT && geometry->min_aspect > 0 && geometry->max_aspect > 0) @@ -3256,17 +6020,17 @@ gdk_window_constrain_size (GdkGeometry *geometry, if (height - delta >= min_height) height -= delta; else - { + { delta = FLOOR (height * geometry->min_aspect - width, xinc); - if (width + delta <= max_width) + if (width + delta <= max_width) width += delta; } } - + if (geometry->max_aspect * height < width) { delta = FLOOR (width - height * geometry->max_aspect, xinc); - if (width - delta >= min_width) + if (width - delta >= min_width) width -= delta; else { @@ -3278,7 +6042,7 @@ gdk_window_constrain_size (GdkGeometry *geometry, } #undef FLOOR - + *new_width = width; *new_height = height; } @@ -3294,9 +6058,9 @@ gdk_window_constrain_size (GdkGeometry *geometry, * modifier mask * * Obtains the current pointer position and modifier state. - * The position is given in coordinates relative to the upper left + * The position is given in coordinates relative to the upper left * corner of @window. - * + * * Return value: the window containing the pointer (as with * gdk_window_at_pointer()), or %NULL if the window containing the * pointer isn't known to GDK @@ -3311,7 +6075,7 @@ gdk_window_get_pointer (GdkWindow *window, gint tmp_x, tmp_y; GdkModifierType tmp_mask; GdkWindow *child; - + g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL); if (window) @@ -3324,7 +6088,7 @@ gdk_window_get_pointer (GdkWindow *window, display = gdk_screen_get_display (screen); window = gdk_screen_get_root_window (screen); - + GDK_NOTE (MULTIHEAD, g_message ("Passing NULL for window to gdk_window_get_pointer()\n" "is not multihead safe")); @@ -3339,6 +6103,8 @@ gdk_window_get_pointer (GdkWindow *window, if (mask) *mask = tmp_mask; + _gdk_display_enable_motion_hints (display); + return child; } @@ -3346,7 +6112,7 @@ gdk_window_get_pointer (GdkWindow *window, * gdk_window_at_pointer: * @win_x: return location for origin of the window under the pointer * @win_y: return location for origin of the window under the pointer - * + * * Obtains the window underneath the mouse pointer, returning the * location of that window in @win_x, @win_y. Returns %NULL if the * window under the mouse pointer is not known to GDK (if the window @@ -3355,7 +6121,7 @@ gdk_window_get_pointer (GdkWindow *window, * * NOTE: For multihead-aware widgets or applications use * gdk_display_get_window_at_pointer() instead. - * + * * Return value: window under the mouse pointer **/ GdkWindow* @@ -3367,10 +6133,10 @@ gdk_window_at_pointer (gint *win_x, /** * gdk_get_default_root_window: - * + * * Obtains the root window (parent all other windows are inside) * for the default display and screen. - * + * * Return value: the default root window **/ GdkWindow * @@ -3382,14 +6148,14 @@ gdk_get_default_root_window (void) /** * gdk_window_foreign_new: * @anid: a native window handle. - * + * * Wraps a native window for the default display in a #GdkWindow. * This may fail if the window has been destroyed. * * For example in the X backend, a native window handle is an Xlib * XID. - * - * Return value: the newly-created #GdkWindow wrapper for the + * + * Return value: the newly-created #GdkWindow wrapper for the * native window or %NULL if the window has been destroyed. **/ GdkWindow * @@ -3398,6 +6164,250 @@ gdk_window_foreign_new (GdkNativeWindow anid) return gdk_window_foreign_new_for_display (gdk_display_get_default (), anid); } +static void +get_all_native_children (GdkWindowObject *private, + GList **native) +{ + GdkWindowObject *child; + GList *l; + + for (l = private->children; l != NULL; l = l->next) + { + child = l->data; + + if (gdk_window_has_impl (child)) + *native = g_list_prepend (*native, child); + else + get_all_native_children (child, native); + } +} + + +static inline void +gdk_window_raise_internal (GdkWindow *window) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowObject *parent = private->parent; + GdkWindowObject *above; + GList *native_children; + GList *l, listhead; + GdkWindowImplIface *impl_iface; + + if (parent) + { + parent->children = g_list_remove (parent->children, window); + parent->children = g_list_prepend (parent->children, window); + } + + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + /* Just do native raise for toplevels */ + if (gdk_window_is_toplevel (private) || + /* The restack_under codepath should work correctly even if the parent + is native, but it relies on the order of ->children to be correct, + and some apps like SWT reorder the x windows without gdks knowledge, + so we use raise directly in order to make these behave as before + when using native windows */ + (gdk_window_has_impl (private) && gdk_window_has_impl (parent))) + { + impl_iface->raise (window); + } + else if (gdk_window_has_impl (private)) + { + above = find_native_sibling_above (parent, private); + if (above) + { + listhead.data = window; + listhead.next = NULL; + listhead.prev = NULL; + impl_iface->restack_under ((GdkWindow *)above, + &listhead); + } + else + impl_iface->raise (window); + } + else + { + native_children = NULL; + get_all_native_children (private, &native_children); + if (native_children != NULL) + { + above = find_native_sibling_above (parent, private); + + if (above) + impl_iface->restack_under ((GdkWindow *)above, + native_children); + else + { + /* Right order, since native_children is bottom-topmost first */ + for (l = native_children; l != NULL; l = l->next) + impl_iface->raise (l->data); + } + + g_list_free (native_children); + } + + } +} + +/* Returns TRUE If the native window was mapped or unmapped */ +static gboolean +set_viewable (GdkWindowObject *w, + gboolean val) +{ + GdkWindowObject *child; + GdkWindowImplIface *impl_iface; + GList *l; + + if (w->viewable == val) + return FALSE; + + w->viewable = val; + + if (val) + recompute_visible_regions (w, FALSE, FALSE); + + for (l = w->children; l != NULL; l = l->next) + { + child = l->data; + + if (GDK_WINDOW_IS_MAPPED (child) && + child->window_type != GDK_WINDOW_FOREIGN) + set_viewable (child, val); + } + + if (!_gdk_native_windows && + gdk_window_has_impl (w) && + w->window_type != GDK_WINDOW_FOREIGN && + !gdk_window_is_toplevel (w)) + { + /* For most native windows we show/hide them not when they are + * mapped/unmapped, because that may not produce the correct results. + * For instance, if a native window have a non-native parent which is + * hidden, but its native parent is viewable then showing the window + * would make it viewable to X but its not viewable wrt the non-native + * hierarchy. In order to handle this we track the gdk side viewability + * and only map really viewable windows. + * + * There are two exceptions though: + * + * For foreign windows we don't want ever change the mapped state + * except when explicitly done via gdk_window_show/hide, as this may + * cause problems for client owning the foreign window when its window + * is suddenly mapped or unmapped. + * + * For toplevel windows embedded in a foreign window (e.g. a plug) + * we sometimes synthesize a map of a window, but the native + * window is really shown by the embedder, so we don't want to + * do the show ourselves. We can't really tell this case from the normal + * toplevel show as such toplevels are seen by gdk as parents of the + * root window, so we make an exception for all toplevels. + * + * Also, when in GDK_NATIVE_WINDOW mode we never need to play games + * like this, so we just always show/hide directly. + */ + + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (w->impl); + if (val) + impl_iface->show ((GdkWindow *)w, FALSE); + else + impl_iface->hide ((GdkWindow *)w); + + return TRUE; + } + + return FALSE; +} + +/* Returns TRUE If the native window was mapped or unmapped */ +gboolean +_gdk_window_update_viewable (GdkWindow *window) +{ + GdkWindowObject *priv = (GdkWindowObject *)window; + gboolean viewable; + + if (priv->window_type == GDK_WINDOW_FOREIGN || + priv->window_type == GDK_WINDOW_ROOT) + viewable = TRUE; + else if (gdk_window_is_toplevel (priv) || + priv->parent->viewable) + viewable = GDK_WINDOW_IS_MAPPED (priv); + else + viewable = FALSE; + + return set_viewable (priv, viewable); +} + +static void +gdk_window_show_internal (GdkWindow *window, gboolean raise) +{ + GdkWindowObject *private; + GdkWindowImplIface *impl_iface; + gboolean was_mapped, was_viewable; + gboolean did_show; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + private = (GdkWindowObject *) window; + if (private->destroyed) + return; + + was_mapped = GDK_WINDOW_IS_MAPPED (window); + was_viewable = private->viewable; + + if (raise) + /* Keep children in (reverse) stacking order */ + gdk_window_raise_internal (window); + + if (gdk_window_has_impl (private)) + { + if (!was_mapped) + gdk_synthesize_window_state (window, + GDK_WINDOW_STATE_WITHDRAWN, + 0); + } + else + { + private->state = 0; + } + + did_show = _gdk_window_update_viewable (window); + + /* If it was already viewable the backend show op won't be called, call it + again to ensure things happen right if the mapped tracking was not right + for e.g. a foreign window. + Dunno if this is strictly needed but its what happened pre-csw. + Also show if not done by gdk_window_update_viewable. */ + if (gdk_window_has_impl (private) && (was_viewable || !did_show)) + { + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + impl_iface->show ((GdkWindow *)private, + !did_show ? was_mapped : TRUE); + } + + if (!was_mapped && !gdk_window_has_impl (private)) + { + if (private->event_mask & GDK_STRUCTURE_MASK) + _gdk_make_event (GDK_WINDOW (private), GDK_MAP, NULL, FALSE); + + if (private->parent && private->parent->event_mask & GDK_SUBSTRUCTURE_MASK) + _gdk_make_event (GDK_WINDOW (private), GDK_MAP, NULL, FALSE); + } + + if (!was_mapped || raise) + { + recompute_visible_regions (private, TRUE, FALSE); + + /* If any decendants became visible we need to send visibility notify */ + gdk_window_update_visibility_recursively (private, NULL); + + if (gdk_window_is_viewable (window)) + { + _gdk_synthesize_crossing_events_for_geometry_change (window); + gdk_window_invalidate_rect (window, NULL, TRUE); + } + } +} + /** * gdk_window_show_unraised: * @window: a #GdkWindow @@ -3413,28 +6423,7 @@ gdk_window_foreign_new (GdkNativeWindow anid) void gdk_window_show_unraised (GdkWindow *window) { - GdkWindowObject *private; - - g_return_if_fail (GDK_IS_WINDOW (window)); - - private = (GdkWindowObject *) window; - if (private->destroyed) - return; - - GDK_WINDOW_IMPL_GET_IFACE (private->impl)->show (window, FALSE); -} - -static inline void -gdk_window_raise_internal (GdkWindow *window) -{ - GdkWindowObject *private = (GdkWindowObject *)window; - GdkWindowObject *parent = private->parent; - - if (parent) - { - parent->children = g_list_remove (parent->children, window); - parent->children = g_list_prepend (parent->children, window); - } + gdk_window_show_internal (window, FALSE); } /** @@ -3453,6 +6442,7 @@ void gdk_window_raise (GdkWindow *window) { GdkWindowObject *private; + GdkRegion *old_region, *new_region; g_return_if_fail (GDK_IS_WINDOW (window)); @@ -3460,10 +6450,28 @@ gdk_window_raise (GdkWindow *window) if (private->destroyed) return; + gdk_window_flush_if_exposing (window); + + old_region = NULL; + if (gdk_window_is_viewable (window) && + !private->input_only) + old_region = gdk_region_copy (private->clip_region); + /* Keep children in (reverse) stacking order */ gdk_window_raise_internal (window); - GDK_WINDOW_IMPL_GET_IFACE (private->impl)->raise (window); + recompute_visible_regions (private, TRUE, FALSE); + + if (old_region) + { + new_region = gdk_region_copy (private->clip_region); + + gdk_region_subtract (new_region, old_region); + gdk_window_invalidate_region (window, new_region, TRUE); + + gdk_region_destroy (old_region); + gdk_region_destroy (new_region); + } } static void @@ -3471,14 +6479,89 @@ gdk_window_lower_internal (GdkWindow *window) { GdkWindowObject *private = (GdkWindowObject *)window; GdkWindowObject *parent = private->parent; + GdkWindowImplIface *impl_iface; + GdkWindowObject *above; + GList *native_children; + GList *l, listhead; if (parent) { parent->children = g_list_remove (parent->children, window); parent->children = g_list_append (parent->children, window); } + + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + /* Just do native lower for toplevels */ + if (gdk_window_is_toplevel (private) || + /* The restack_under codepath should work correctly even if the parent + is native, but it relies on the order of ->children to be correct, + and some apps like SWT reorder the x windows without gdks knowledge, + so we use lower directly in order to make these behave as before + when using native windows */ + (gdk_window_has_impl (private) && gdk_window_has_impl (parent))) + { + impl_iface->lower (window); + } + else if (gdk_window_has_impl (private)) + { + above = find_native_sibling_above (parent, private); + if (above) + { + listhead.data = window; + listhead.next = NULL; + listhead.prev = NULL; + impl_iface->restack_under ((GdkWindow *)above, &listhead); + } + else + impl_iface->raise (window); + } + else + { + native_children = NULL; + get_all_native_children (private, &native_children); + if (native_children != NULL) + { + above = find_native_sibling_above (parent, private); + + if (above) + impl_iface->restack_under ((GdkWindow *)above, + native_children); + else + { + /* Right order, since native_children is bottom-topmost first */ + for (l = native_children; l != NULL; l = l->next) + impl_iface->raise (l->data); + } + + g_list_free (native_children); + } + + } } +static void +gdk_window_invalidate_in_parent (GdkWindowObject *private) +{ + GdkRectangle r, child; + + if (gdk_window_is_toplevel (private)) + return; + + /* get the visible rectangle of the parent */ + r.x = r.y = 0; + r.width = private->parent->width; + r.height = private->parent->height; + + child.x = private->x; + child.y = private->y; + child.width = private->width; + child.height = private->height; + gdk_rectangle_intersect (&r, &child, &r); + + gdk_window_invalidate_rect (GDK_WINDOW (private->parent), &r, TRUE); +} + + /** * gdk_window_lower: * @window: a #GdkWindow @@ -3505,12 +6588,136 @@ gdk_window_lower (GdkWindow *window) if (private->destroyed) return; + gdk_window_flush_if_exposing (window); + /* Keep children in (reverse) stacking order */ gdk_window_lower_internal (window); - GDK_WINDOW_IMPL_GET_IFACE (private->impl)->lower (window); + recompute_visible_regions (private, TRUE, FALSE); + + _gdk_synthesize_crossing_events_for_geometry_change (window); + gdk_window_invalidate_in_parent (private); } +/** + * gdk_window_restack: + * @window: a #GdkWindow + * @sibling: a #GdkWindow that is a sibling of @window, or %NULL + * @above: a boolean + * + * Changes the position of @window in the Z-order (stacking order), so that + * it is above @sibling (if @above is %TRUE) or below @sibling (if @above is + * %FALSE). + * + * If @sibling is %NULL, then this either raises (if @above is %TRUE) or + * lowers the window. + * + * If @window is a toplevel, the window manager may choose to deny the + * request to move the window in the Z-order, gdk_window_restack() only + * requests the restack, does not guarantee it. + * + * Since: 2.18 + */ +void +gdk_window_restack (GdkWindow *window, + GdkWindow *sibling, + gboolean above) +{ + GdkWindowObject *private; + GdkWindowImplIface *impl_iface; + GdkWindowObject *parent; + GdkWindowObject *above_native; + GList *sibling_link; + GList *native_children; + GList *l, listhead; + + g_return_if_fail (GDK_IS_WINDOW (window)); + g_return_if_fail (sibling == NULL || GDK_IS_WINDOW (sibling)); + + private = (GdkWindowObject *) window; + if (private->destroyed) + return; + + if (sibling == NULL) + { + if (above) + gdk_window_raise (window); + else + gdk_window_lower (window); + return; + } + + gdk_window_flush_if_exposing (window); + + if (gdk_window_is_toplevel (private)) + { + g_return_if_fail (gdk_window_is_toplevel (GDK_WINDOW_OBJECT (sibling))); + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + impl_iface->restack_toplevel (window, sibling, above); + return; + } + + parent = private->parent; + if (parent) + { + sibling_link = g_list_find (parent->children, sibling); + g_return_if_fail (sibling_link != NULL); + if (sibling_link == NULL) + return; + + parent->children = g_list_remove (parent->children, window); + if (above) + parent->children = g_list_insert_before (parent->children, + sibling_link, + window); + else + parent->children = g_list_insert_before (parent->children, + sibling_link->next, + window); + + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + if (gdk_window_has_impl (private)) + { + above_native = find_native_sibling_above (parent, private); + if (above_native) + { + listhead.data = window; + listhead.next = NULL; + listhead.prev = NULL; + impl_iface->restack_under ((GdkWindow *)above_native, &listhead); + } + else + impl_iface->raise (window); + } + else + { + native_children = NULL; + get_all_native_children (private, &native_children); + if (native_children != NULL) + { + above_native = find_native_sibling_above (parent, private); + if (above_native) + impl_iface->restack_under ((GdkWindow *)above_native, + native_children); + else + { + /* Right order, since native_children is bottom-topmost first */ + for (l = native_children; l != NULL; l = l->next) + impl_iface->raise (l->data); + } + + g_list_free (native_children); + } + } + } + + recompute_visible_regions (private, TRUE, FALSE); + + _gdk_synthesize_crossing_events_for_geometry_change (window); + gdk_window_invalidate_in_parent (private); +} + + /** * gdk_window_show: * @window: a #GdkWindow @@ -3528,18 +6735,7 @@ gdk_window_lower (GdkWindow *window) void gdk_window_show (GdkWindow *window) { - GdkWindowObject *private; - - g_return_if_fail (GDK_IS_WINDOW (window)); - - private = (GdkWindowObject *) window; - if (private->destroyed) - return; - - /* Keep children in (reverse) stacking order */ - gdk_window_raise_internal (window); - - GDK_WINDOW_IMPL_GET_IFACE (private->impl)->show (window, TRUE); + gdk_window_show_internal (window, TRUE); } /** @@ -3555,6 +6751,8 @@ void gdk_window_hide (GdkWindow *window) { GdkWindowObject *private; + GdkWindowImplIface *impl_iface; + gboolean was_mapped, did_hide; g_return_if_fail (GDK_IS_WINDOW (window)); @@ -3562,7 +6760,72 @@ gdk_window_hide (GdkWindow *window) if (private->destroyed) return; - GDK_WINDOW_IMPL_GET_IFACE (private->impl)->hide (window); + was_mapped = GDK_WINDOW_IS_MAPPED (private); + + if (gdk_window_has_impl (private)) + { + + if (GDK_WINDOW_IS_MAPPED (window)) + gdk_synthesize_window_state (window, + 0, + GDK_WINDOW_STATE_WITHDRAWN); + } + else if (was_mapped) + { + GdkDisplay *display; + + /* May need to break grabs on children */ + display = gdk_drawable_get_display (window); + + if (_gdk_display_end_pointer_grab (display, + _gdk_windowing_window_get_next_serial (display), + window, + TRUE)) + gdk_display_pointer_ungrab (display, GDK_CURRENT_TIME); + + if (display->keyboard_grab.window != NULL) + { + if (is_parent_of (window, display->keyboard_grab.window)) + { + /* Call this ourselves, even though gdk_display_keyboard_ungrab + does so too, since we want to pass implicit == TRUE so the + broken grab event is generated */ + _gdk_display_unset_has_keyboard_grab (display, + TRUE); + gdk_display_keyboard_ungrab (display, GDK_CURRENT_TIME); + } + } + + private->state = GDK_WINDOW_STATE_WITHDRAWN; + } + + did_hide = _gdk_window_update_viewable (window); + + /* Hide foreign window as those are not handled by update_viewable. */ + if (gdk_window_has_impl (private) && (!did_hide)) + { + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + impl_iface->hide (window); + } + + recompute_visible_regions (private, TRUE, FALSE); + + /* all decendants became non-visible, we need to send visibility notify */ + gdk_window_update_visibility_recursively (private, NULL); + + if (was_mapped && !gdk_window_has_impl (private)) + { + if (private->event_mask & GDK_STRUCTURE_MASK) + _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE); + + if (private->parent && private->parent->event_mask & GDK_SUBSTRUCTURE_MASK) + _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE); + + _gdk_synthesize_crossing_events_for_geometry_change (GDK_WINDOW (private->parent)); + } + + /* Invalidate the rect */ + gdk_window_invalidate_in_parent (private); } /** @@ -3577,6 +6840,8 @@ void gdk_window_withdraw (GdkWindow *window) { GdkWindowObject *private; + GdkWindowImplIface *impl_iface; + gboolean was_mapped; g_return_if_fail (GDK_IS_WINDOW (window)); @@ -3584,7 +6849,26 @@ gdk_window_withdraw (GdkWindow *window) if (private->destroyed) return; - GDK_WINDOW_IMPL_GET_IFACE (private->impl)->withdraw (window); + was_mapped = GDK_WINDOW_IS_MAPPED (private); + + if (gdk_window_has_impl (private)) + { + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + impl_iface->withdraw (window); + + if (was_mapped) + { + if (private->event_mask & GDK_STRUCTURE_MASK) + _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE); + + if (private->parent && private->parent->event_mask & GDK_SUBSTRUCTURE_MASK) + _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE); + + _gdk_synthesize_crossing_events_for_geometry_change (GDK_WINDOW (private->parent)); + } + + recompute_visible_regions (private, TRUE, FALSE); + } } /** @@ -3602,6 +6886,8 @@ gdk_window_set_events (GdkWindow *window, GdkEventMask event_mask) { GdkWindowObject *private; + GdkWindowImplIface *impl_iface; + GdkDisplay *display; g_return_if_fail (GDK_IS_WINDOW (window)); @@ -3609,7 +6895,21 @@ gdk_window_set_events (GdkWindow *window, if (private->destroyed) return; - GDK_WINDOW_IMPL_GET_IFACE (private->impl)->set_events (window, event_mask); + /* If motion hint is disabled, enable motion events again */ + display = gdk_drawable_get_display (window); + if ((private->event_mask & GDK_POINTER_MOTION_HINT_MASK) && + !(event_mask & GDK_POINTER_MOTION_HINT_MASK)) + _gdk_display_enable_motion_hints (display); + + private->event_mask = event_mask; + + if (gdk_window_has_impl (private)) + { + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + impl_iface->set_events (window, + get_native_event_mask (private)); + } + } /** @@ -3631,9 +6931,347 @@ gdk_window_get_events (GdkWindow *window) if (private->destroyed) return 0; - return GDK_WINDOW_IMPL_GET_IFACE (private->impl)->get_events (window); + return private->event_mask; } +static void +gdk_window_move_resize_toplevel (GdkWindow *window, + gboolean with_move, + gint x, + gint y, + gint width, + gint height) +{ + GdkWindowObject *private; + GdkRegion *old_region, *new_region; + GdkWindowImplIface *impl_iface; + gboolean expose; + int old_x, old_y, old_abs_x, old_abs_y; + int dx, dy; + gboolean is_resize; + + private = (GdkWindowObject *) window; + + expose = FALSE; + old_region = NULL; + + old_x = private->x; + old_y = private->y; + + is_resize = (width != -1) || (height != -1); + + if (gdk_window_is_viewable (window) && + !private->input_only) + { + expose = TRUE; + old_region = gdk_region_copy (private->clip_region); + } + + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + impl_iface->move_resize (window, with_move, x, y, width, height); + + dx = private->x - old_x; + dy = private->y - old_y; + + old_abs_x = private->abs_x; + old_abs_y = private->abs_y; + + /* Avoid recomputing for pure toplevel moves, for performance reasons */ + if (is_resize) + recompute_visible_regions (private, TRUE, FALSE); + + if (expose) + { + new_region = gdk_region_copy (private->clip_region); + + /* This is the newly exposed area (due to any resize), + * X will expose it, but lets do that without the + * roundtrip + */ + gdk_region_subtract (new_region, old_region); + gdk_window_invalidate_region (window, new_region, TRUE); + + gdk_region_destroy (old_region); + gdk_region_destroy (new_region); + } + + _gdk_synthesize_crossing_events_for_geometry_change (window); +} + + +static void +move_native_children (GdkWindowObject *private) +{ + GList *l; + GdkWindowObject *child; + GdkWindowImplIface *impl_iface; + + for (l = private->children; l; l = l->next) + { + child = l->data; + + if (child->impl != private->impl) + { + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (child->impl); + impl_iface->move_resize ((GdkWindow *)child, TRUE, + child->x, child->y, + child->width, child->height); + } + else + move_native_children (child); + } +} + +static gboolean +collect_native_child_region_helper (GdkWindowObject *window, + GdkWindow *impl, + GdkRegion **region, + int x_offset, + int y_offset) +{ + GdkWindowObject *child; + GdkRegion *tmp; + GList *l; + + for (l = window->children; l != NULL; l = l->next) + { + child = l->data; + + if (!GDK_WINDOW_IS_MAPPED (child) || child->input_only) + continue; + + if (child->impl != impl) + { + tmp = gdk_region_copy (child->clip_region); + gdk_region_offset (tmp, + x_offset + child->x, + y_offset + child->y); + if (*region == NULL) + *region = tmp; + else + { + gdk_region_union (*region, tmp); + gdk_region_destroy (tmp); + } + } + else + collect_native_child_region_helper (child, impl, region, + x_offset + child->x, + y_offset + child->y); + } + + return FALSE; +} + +static GdkRegion * +collect_native_child_region (GdkWindowObject *window, + gboolean include_this) +{ + GdkRegion *region; + + if (include_this && gdk_window_has_impl (window) && window->viewable) + return gdk_region_copy (window->clip_region); + + region = NULL; + + collect_native_child_region_helper (window, window->impl, ®ion, 0, 0); + + return region; +} + + +static void +gdk_window_move_resize_internal (GdkWindow *window, + gboolean with_move, + gint x, + gint y, + gint width, + gint height) +{ + GdkWindowObject *private; + GdkRegion *old_region, *new_region, *copy_area; + GdkRegion *old_native_child_region, *new_native_child_region; + GdkWindowObject *impl_window; + GdkWindowImplIface *impl_iface; + gboolean expose; + int old_x, old_y, old_abs_x, old_abs_y; + int dx, dy; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + private = (GdkWindowObject *) window; + if (private->destroyed) + return; + + if (gdk_window_is_toplevel (private)) + { + gdk_window_move_resize_toplevel (window, with_move, x, y, width, height); + return; + } + + /* Bail early if no change */ + if (private->width == width && + private->height == height && + (!with_move || + (private->x == x && + private->y == y))) + return; + + gdk_window_flush_if_exposing (window); + + /* Handle child windows */ + + expose = FALSE; + old_region = NULL; + + impl_window = gdk_window_get_impl_window (private); + + old_x = private->x; + old_y = private->y; + + old_native_child_region = NULL; + if (gdk_window_is_viewable (window) && + !private->input_only) + { + expose = TRUE; + + old_region = gdk_region_copy (private->clip_region); + /* Adjust region to parent window coords */ + gdk_region_offset (old_region, private->x, private->y); + + old_native_child_region = collect_native_child_region (private, TRUE); + if (old_native_child_region) + { + /* Adjust region to parent window coords */ + gdk_region_offset (old_native_child_region, private->x, private->y); + + /* Any native window move will immediately copy stuff to the destination, which may overwrite a + * source or destination for a delayed GdkWindowRegionMove. So, we need + * to flush those here for the parent window and all overlapped subwindows + * of it. And we need to do this before setting the new clips as those will be + * affecting this. + */ + gdk_window_flush_recursive (private->parent); + } + } + + /* Set the new position and size */ + if (with_move) + { + private->x = x; + private->y = y; + } + if (!(width < 0 && height < 0)) + { + if (width < 1) + width = 1; + private->width = width; + if (height < 1) + height = 1; + private->height = height; + } + + dx = private->x - old_x; + dy = private->y - old_y; + + old_abs_x = private->abs_x; + old_abs_y = private->abs_y; + + recompute_visible_regions (private, TRUE, FALSE); + + new_native_child_region = NULL; + if (old_native_child_region) + { + new_native_child_region = collect_native_child_region (private, TRUE); + /* Adjust region to parent window coords */ + gdk_region_offset (new_native_child_region, private->x, private->y); + } + + if (gdk_window_has_impl (private)) + { + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + + /* Do the actual move after recomputing things, as this will have set the shape to + the now correct one, thus avoiding copying regions that should not be copied. */ + impl_iface->move_resize (window, TRUE, + private->x, private->y, + private->width, private->height); + } + else if (old_abs_x != private->abs_x || + old_abs_y != private->abs_y) + move_native_children (private); + + if (expose) + { + new_region = gdk_region_copy (private->clip_region); + /* Adjust region to parent window coords */ + gdk_region_offset (new_region, private->x, private->y); + + /* copy_area: + * Part of the data at the new location can be copied from the + * old location, this area is the intersection of the old region + * moved as the copy will move it and then intersected with + * the new region. + * + * new_region: + * Everything in the old and new regions that is not copied must be + * invalidated (including children) as this is newly exposed + */ + copy_area = gdk_region_copy (new_region); + + gdk_region_union (new_region, old_region); + + if (old_native_child_region) + { + /* Don't copy from inside native children, as this is copied by + * the native window move. + */ + gdk_region_subtract (old_region, old_native_child_region); + } + gdk_region_offset (old_region, dx, dy); + + gdk_region_intersect (copy_area, old_region); + + if (new_native_child_region) + { + /* Don't copy any bits that would cause a read from the moved + native windows, as we can't read that data */ + gdk_region_offset (new_native_child_region, dx, dy); + gdk_region_subtract (copy_area, new_native_child_region); + } + + gdk_region_subtract (new_region, copy_area); + + /* Convert old region to impl coords */ + gdk_region_offset (old_region, -dx + private->abs_x - private->x, -dy + private->abs_y - private->y); + + /* convert from parent coords to impl */ + gdk_region_offset (copy_area, private->abs_x - private->x, private->abs_y - private->y); + + move_region_on_impl (impl_window, copy_area, dx, dy); /* takes ownership of copy_area */ + + /* Invalidate affected part in the parent window + * (no higher window should be affected) + * We also invalidate any children in that area, which could include + * this window if it still overlaps that area. + */ + gdk_window_invalidate_region (GDK_WINDOW (private->parent), new_region, TRUE); + + gdk_region_destroy (old_region); + gdk_region_destroy (new_region); + } + + if (old_native_child_region) + { + gdk_region_destroy (old_native_child_region); + gdk_region_destroy (new_native_child_region); + } + + _gdk_synthesize_crossing_events_for_geometry_change (window); +} + + + /** * gdk_window_move: * @window: a #GdkWindow @@ -3654,15 +7292,7 @@ gdk_window_move (GdkWindow *window, gint x, gint y) { - GdkWindowObject *private; - - g_return_if_fail (GDK_IS_WINDOW (window)); - - private = (GdkWindowObject *) window; - if (private->destroyed) - return; - - GDK_WINDOW_IMPL_GET_IFACE (private->impl)->move_resize (window, TRUE, x, y, -1, -1); + gdk_window_move_resize_internal (window, TRUE, x, y, -1, -1); } /** @@ -3685,15 +7315,7 @@ gdk_window_resize (GdkWindow *window, gint width, gint height) { - GdkWindowObject *private; - - g_return_if_fail (GDK_IS_WINDOW (window)); - - private = (GdkWindowObject *) window; - if (private->destroyed) - return; - - GDK_WINDOW_IMPL_GET_IFACE (private->impl)->move_resize (window, FALSE, 0, 0, width, height); + gdk_window_move_resize_internal (window, FALSE, 0, 0, width, height); } @@ -3717,15 +7339,7 @@ gdk_window_move_resize (GdkWindow *window, gint width, gint height) { - GdkWindowObject *private; - - g_return_if_fail (GDK_IS_WINDOW (window)); - - private = (GdkWindowObject *) window; - if (private->destroyed) - return; - - GDK_WINDOW_IMPL_GET_IFACE (private->impl)->move_resize (window, TRUE, x, y, width, height); + gdk_window_move_resize_internal (window, TRUE, x, y, width, height); } @@ -3753,6 +7367,10 @@ gdk_window_scroll (GdkWindow *window, gint dy) { GdkWindowObject *private = (GdkWindowObject *) window; + GdkWindowObject *impl_window; + GdkRegion *copy_area, *noncopy_area; + GdkRegion *old_native_child_region, *new_native_child_region; + GList *tmp_list; g_return_if_fail (GDK_IS_WINDOW (window)); @@ -3762,7 +7380,85 @@ gdk_window_scroll (GdkWindow *window, if (private->destroyed) return; - GDK_WINDOW_IMPL_GET_IFACE (private->impl)->scroll (window, dx, dy); + gdk_window_flush_if_exposing (window); + + old_native_child_region = collect_native_child_region (private, FALSE); + if (old_native_child_region) + { + /* Any native window move will immediately copy stuff to the destination, which may overwrite a + * source or destination for a delayed GdkWindowRegionMove. So, we need + * to flush those here for the window and all overlapped subwindows + * of it. And we need to do this before setting the new clips as those will be + * affecting this. + */ + gdk_window_flush_recursive (private); + } + + + /* First move all child windows, without causing invalidation */ + + tmp_list = private->children; + while (tmp_list) + { + GdkWindow *child = GDK_WINDOW (tmp_list->data); + GdkWindowObject *child_obj = GDK_WINDOW_OBJECT (child); + + /* Just update the positions, the bits will move with the copy */ + child_obj->x += dx; + child_obj->y += dy; + + tmp_list = tmp_list->next; + } + + recompute_visible_regions (private, FALSE, TRUE); + + new_native_child_region = NULL; + if (old_native_child_region) + new_native_child_region = collect_native_child_region (private, FALSE); + + move_native_children (private); + + /* Then copy the actual bits of the window w/ child windows */ + + impl_window = gdk_window_get_impl_window (private); + + /* Calculate the area that can be gotten by copying the old area */ + copy_area = gdk_region_copy (private->clip_region); + if (old_native_child_region) + { + /* Don't copy from inside native children, as this is copied by + * the native window move. + */ + gdk_region_subtract (copy_area, old_native_child_region); + + /* Don't copy any bits that would cause a read from the moved + native windows, as we can't read that data */ + gdk_region_subtract (copy_area, new_native_child_region); + } + gdk_region_offset (copy_area, dx, dy); + gdk_region_intersect (copy_area, private->clip_region); + + /* And the rest need to be invalidated */ + noncopy_area = gdk_region_copy (private->clip_region); + gdk_region_subtract (noncopy_area, copy_area); + + /* convert from window coords to impl */ + gdk_region_offset (copy_area, private->abs_x, private->abs_y); + + move_region_on_impl (impl_window, copy_area, dx, dy); /* takes ownership of copy_area */ + + /* Invalidate not copied regions */ + gdk_window_invalidate_region (window, noncopy_area, TRUE); + + gdk_region_destroy (noncopy_area); + + if (old_native_child_region) + { + gdk_region_destroy (old_native_child_region); + gdk_region_destroy (new_native_child_region); + } + + _gdk_synthesize_crossing_events_for_geometry_change (window); } /** @@ -3787,6 +7483,9 @@ gdk_window_move_region (GdkWindow *window, gint dy) { GdkWindowObject *private = (GdkWindowObject *) window; + GdkWindowObject *impl_window; + GdkRegion *nocopy_area; + GdkRegion *copy_area; g_return_if_fail (GDK_IS_WINDOW (window)); g_return_if_fail (region != NULL); @@ -3797,7 +7496,29 @@ gdk_window_move_region (GdkWindow *window, if (private->destroyed) return; - GDK_WINDOW_IMPL_GET_IFACE (private->impl)->move_region (window, region, dx, dy); + impl_window = gdk_window_get_impl_window (private); + + /* compute source regions */ + copy_area = gdk_region_copy (region); + gdk_region_intersect (copy_area, private->clip_region_with_children); + + /* compute destination regions */ + gdk_region_offset (copy_area, dx, dy); + gdk_region_intersect (copy_area, private->clip_region_with_children); + + /* Invalidate parts of the region (source and dest) not covered + by the copy */ + nocopy_area = gdk_region_copy (region); + gdk_region_offset (nocopy_area, dx, dy); + gdk_region_union (nocopy_area, region); + gdk_region_subtract (nocopy_area, copy_area); + + /* convert from window coords to impl */ + gdk_region_offset (copy_area, private->abs_x, private->abs_y); + move_region_on_impl (impl_window, copy_area, dx, dy); /* Takes ownership of copy_area */ + + gdk_window_invalidate_region (window, nocopy_area, FALSE); + gdk_region_destroy (nocopy_area); } /** @@ -3820,12 +7541,30 @@ gdk_window_set_background (GdkWindow *window, const GdkColor *color) { GdkWindowObject *private; + GdkColormap *colormap = gdk_drawable_get_colormap (window); + GdkWindowImplIface *impl_iface; g_return_if_fail (GDK_IS_WINDOW (window)); private = (GdkWindowObject *) window; - GDK_WINDOW_IMPL_GET_IFACE (private->impl)->set_background (window, color); + private->bg_color = *color; + gdk_colormap_query_color (colormap, private->bg_color.pixel, &private->bg_color); + + if (private->bg_pixmap && + private->bg_pixmap != GDK_PARENT_RELATIVE_BG && + private->bg_pixmap != GDK_NO_BG) + g_object_unref (private->bg_pixmap); + + private->bg_pixmap = NULL; + + if (!GDK_WINDOW_DESTROYED (window) && + gdk_window_has_impl (private) && + !private->input_only) + { + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + impl_iface->set_background (window, &private->bg_color); + } } /** @@ -3860,6 +7599,7 @@ gdk_window_set_back_pixmap (GdkWindow *window, gboolean parent_relative) { GdkWindowObject *private; + GdkWindowImplIface *impl_iface; g_return_if_fail (GDK_IS_WINDOW (window)); g_return_if_fail (pixmap == NULL || !parent_relative); @@ -3867,7 +7607,58 @@ gdk_window_set_back_pixmap (GdkWindow *window, private = (GdkWindowObject *) window; - GDK_WINDOW_IMPL_GET_IFACE (private->impl)->set_back_pixmap (window, pixmap, parent_relative); + if (pixmap && !gdk_drawable_get_colormap (pixmap)) + { + g_warning ("gdk_window_set_back_pixmap(): pixmap must have a colormap"); + return; + } + + if (private->bg_pixmap && + private->bg_pixmap != GDK_PARENT_RELATIVE_BG && + private->bg_pixmap != GDK_NO_BG) + g_object_unref (private->bg_pixmap); + + if (parent_relative) + private->bg_pixmap = GDK_PARENT_RELATIVE_BG; + else if (pixmap) + private->bg_pixmap = g_object_ref (pixmap); + else + private->bg_pixmap = GDK_NO_BG; + + if (!GDK_WINDOW_DESTROYED (window) && + gdk_window_has_impl (private) && + !private->input_only) + { + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + impl_iface->set_back_pixmap (window, private->bg_pixmap); + } +} + +/** + * gdk_window_get_cursor: + * @window: a #GdkWindow + * + * Retrieves a #GdkCursor pointer for the cursor currently set on the + * specified #GdkWindow, or %NULL. If the return value is %NULL then + * there is no custom cursor set on the specified window, and it is + * using the cursor for its parent window. + * + * Return value: a #GdkCursor, or %NULL. The returned object is owned + * by the #GdkWindow and should not be unreferenced directly. Use + * gdk_window_set_cursor() to unset the cursor of the window + * + * Since: 2.18 + */ +GdkCursor * +gdk_window_get_cursor (GdkWindow *window) +{ + GdkWindowObject *private; + + g_return_val_if_fail (GDK_IS_WINDOW (window), NULL); + + private = (GdkWindowObject *) window; + + return private->cursor; } /** @@ -3875,10 +7666,10 @@ gdk_window_set_back_pixmap (GdkWindow *window, * @window: a #GdkWindow * @cursor: a cursor * - * Sets the mouse pointer for a #GdkWindow. Use gdk_cursor_new_for_display() - * or gdk_cursor_new_from_pixmap() to create the cursor. To make the cursor - * invisible, use %GDK_BLANK_CURSOR. Passing %NULL for the @cursor argument - * to gdk_window_set_cursor() means that @window will use the cursor of its + * Sets the mouse pointer for a #GdkWindow. Use gdk_cursor_new_for_display() + * or gdk_cursor_new_from_pixmap() to create the cursor. To make the cursor + * invisible, use %GDK_BLANK_CURSOR. Passing %NULL for the @cursor argument + * to gdk_window_set_cursor() means that @window will use the cursor of its * parent window. Most windows should use this default. */ void @@ -3886,12 +7677,37 @@ gdk_window_set_cursor (GdkWindow *window, GdkCursor *cursor) { GdkWindowObject *private; + GdkWindowImplIface *impl_iface; + GdkDisplay *display; g_return_if_fail (GDK_IS_WINDOW (window)); private = (GdkWindowObject *) window; + display = gdk_drawable_get_display (window); - GDK_WINDOW_IMPL_GET_IFACE (private->impl)->set_cursor (window, cursor); + if (private->cursor) + { + gdk_cursor_unref (private->cursor); + private->cursor = NULL; + } + + if (!GDK_WINDOW_DESTROYED (window)) + { + if (cursor) + private->cursor = gdk_cursor_ref (cursor); + + if (_gdk_native_windows || + private->window_type == GDK_WINDOW_ROOT || + private->window_type == GDK_WINDOW_FOREIGN) + { + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + impl_iface->set_cursor (window, cursor); + } + else if (_gdk_window_event_parent_of (window, display->pointer_info.window_under_pointer)) + update_cursor (display); + + g_object_notify (G_OBJECT (window), "cursor"); + } } /** @@ -3934,13 +7750,14 @@ gdk_window_get_geometry (GdkWindow *window, gint *height, gint *depth) { - GdkWindowObject *private; + GdkWindowObject *private, *parent; + GdkWindowImplIface *impl_iface; if (!window) { GDK_NOTE (MULTIHEAD, g_message ("gdk_window_get_geometry(): Window needs " - "to be non-NULL to be multi head safe")); + "to be non-NULL to be multi head safe")); window = gdk_screen_get_root_window ((gdk_screen_get_default ())); } @@ -3950,9 +7767,36 @@ gdk_window_get_geometry (GdkWindow *window, if (!GDK_WINDOW_DESTROYED (window)) { - GDK_WINDOW_IMPL_GET_IFACE (private->impl)->get_geometry (window, x, y, - width, height, - depth); + if (gdk_window_has_impl (private)) + { + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + impl_iface->get_geometry (window, x, y, + width, height, + depth); + /* This reports the position wrt to the native parent, we need to convert + it to be relative to the client side parent */ + parent = private->parent; + if (parent && !gdk_window_has_impl (parent)) + { + if (x) + *x -= parent->abs_x; + if (y) + *y -= parent->abs_y; + } + } + else + { + if (x) + *x = private->x; + if (y) + *y = private->y; + if (width) + *width = private->width; + if (height) + *height = private->height; + if (depth) + *depth = private->depth; + } } } @@ -3975,12 +7819,116 @@ gdk_window_get_origin (GdkWindow *window, gint *y) { GdkWindowObject *private; + GdkWindowImplIface *impl_iface; g_return_val_if_fail (GDK_IS_WINDOW (window), 0); + if (GDK_WINDOW_DESTROYED (window)) + { + if (x) + *x = 0; + if (y) + *y = 0; + return 0; + } + private = (GdkWindowObject *) window; - return GDK_WINDOW_IMPL_GET_IFACE (private->impl)->get_origin (window, x, y); + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + impl_iface->get_root_coords (window, + private->abs_x, + private->abs_y, + x, y); + + return TRUE; +} + +/** + * gdk_window_get_root_coords: + * @window: a #GdkWindow + * @x: X coordinate in window + * @y: Y coordinate in window + * @root_x: return location for X coordinate + * @root_y: return location for Y coordinate + * + * Obtains the position of a window position in root + * window coordinates. This is similar to + * gdk_window_get_origin() but allows you go pass + * in any position in the window, not just the origin. + */ +void +gdk_window_get_root_coords (GdkWindow *window, + gint x, + gint y, + gint *root_x, + gint *root_y) +{ + GdkWindowObject *private; + GdkWindowImplIface *impl_iface; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + private = (GdkWindowObject *) window; + + if (GDK_WINDOW_DESTROYED (window)) + { + if (x) + *root_x = x; + if (y) + *root_y = y; + return; + } + + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + impl_iface->get_root_coords (window, + x + private->abs_x, + y + private->abs_y, + root_x, root_y); +} + + +/** + * gdk_window_get_deskrelative_origin: + * @window: a toplevel #GdkWindow + * @x: return location for X coordinate + * @y: return location for Y coordinate + * + * This gets the origin of a #GdkWindow relative to + * an Enlightenment-window-manager desktop. As long as you don't + * assume that the user's desktop/workspace covers the entire + * root window (i.e. you don't assume that the desktop begins + * at root window coordinate 0,0) this function is not necessary. + * It's deprecated for that reason. + * + * Return value: not meaningful + **/ +gboolean +gdk_window_get_deskrelative_origin (GdkWindow *window, + gint *x, + gint *y) +{ + GdkWindowObject *private; + GdkWindowImplIface *impl_iface; + gboolean return_val = FALSE; + gint tx = 0; + gint ty = 0; + + g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE); + + private = (GdkWindowObject *) window; + + if (!GDK_WINDOW_DESTROYED (window)) + { + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + return_val = impl_iface->get_deskrelative_origin (window, &tx, &ty); + + if (x) + *x = tx + private->abs_x; + if (y) + *y = ty + private->abs_y; + } + + return return_val; } /** @@ -4010,15 +7958,26 @@ void gdk_window_shape_combine_mask (GdkWindow *window, GdkBitmap *mask, gint x, - gint y) + gint y) { GdkWindowObject *private; + GdkRegion *region; g_return_if_fail (GDK_IS_WINDOW (window)); private = (GdkWindowObject *) window; - GDK_WINDOW_IMPL_GET_IFACE (private->impl)->shape_combine_mask (window, mask, x, y); + if (mask) + region = _gdk_windowing_get_shape_for_mask (mask); + else + region = NULL; + + gdk_window_shape_combine_region (window, + region, + x, y); + + if (region) + gdk_region_destroy (region); } /** @@ -4046,17 +8005,96 @@ gdk_window_shape_combine_mask (GdkWindow *window, */ void gdk_window_shape_combine_region (GdkWindow *window, - const GdkRegion *shape_region, - gint offset_x, - gint offset_y) + const GdkRegion *shape_region, + gint offset_x, + gint offset_y) { GdkWindowObject *private; + GdkRegion *old_region, *new_region, *diff; g_return_if_fail (GDK_IS_WINDOW (window)); private = (GdkWindowObject *) window; - GDK_WINDOW_IMPL_GET_IFACE (private->impl)->shape_combine_region (window, shape_region, offset_x, offset_y); + if (GDK_WINDOW_DESTROYED (window)) + return; + + private->shaped = (shape_region != NULL); + + if (private->shape) + gdk_region_destroy (private->shape); + + old_region = NULL; + if (GDK_WINDOW_IS_MAPPED (window)) + old_region = gdk_region_copy (private->clip_region); + + if (shape_region) + { + private->shape = gdk_region_copy (shape_region); + gdk_region_offset (private->shape, offset_x, offset_y); + } + else + private->shape = NULL; + + recompute_visible_regions (private, TRUE, FALSE); + + if (gdk_window_has_impl (private) && + !should_apply_clip_as_shape (private)) + apply_shape (private, private->shape); + + if (old_region) + { + new_region = gdk_region_copy (private->clip_region); + + /* New area in the window, needs invalidation */ + diff = gdk_region_copy (new_region); + gdk_region_subtract (diff, old_region); + + gdk_window_invalidate_region (window, diff, TRUE); + + gdk_region_destroy (diff); + + if (!gdk_window_is_toplevel (private)) + { + /* New area in the non-root parent window, needs invalidation */ + diff = gdk_region_copy (old_region); + gdk_region_subtract (diff, new_region); + + /* Adjust region to parent window coords */ + gdk_region_offset (diff, private->x, private->y); + + gdk_window_invalidate_region (GDK_WINDOW (private->parent), diff, TRUE); + + gdk_region_destroy (diff); + } + + gdk_region_destroy (new_region); + gdk_region_destroy (old_region); + } +} + +static void +do_child_shapes (GdkWindow *window, + gboolean merge) +{ + GdkWindowObject *private; + GdkRectangle r; + GdkRegion *region; + + private = (GdkWindowObject *) window; + + r.x = 0; + r.y = 0; + r.width = private->width; + r.height = private->height; + + region = gdk_region_rectangle (&r); + remove_child_area (private, NULL, FALSE, region); + + if (merge && private->shape) + gdk_region_subtract (region, private->shape); + + gdk_window_shape_combine_region (window, region, 0, 0); } /** @@ -4071,13 +8109,9 @@ gdk_window_shape_combine_region (GdkWindow *window, void gdk_window_set_child_shapes (GdkWindow *window) { - GdkWindowObject *private; - g_return_if_fail (GDK_IS_WINDOW (window)); - private = (GdkWindowObject *) window; - - GDK_WINDOW_IMPL_GET_IFACE (private->impl)->set_child_shapes (window); + do_child_shapes (window, FALSE); } /** @@ -4095,14 +8129,194 @@ gdk_window_set_child_shapes (GdkWindow *window) */ void gdk_window_merge_child_shapes (GdkWindow *window) +{ + g_return_if_fail (GDK_IS_WINDOW (window)); + + do_child_shapes (window, TRUE); +} + +/** + * gdk_window_input_shape_combine_mask: + * @window: a #GdkWindow + * @mask: shape mask, or %NULL + * @x: X position of shape mask with respect to @window + * @y: Y position of shape mask with respect to @window + * + * Like gdk_window_shape_combine_mask(), but the shape applies + * only to event handling. Mouse events which happen while + * the pointer position corresponds to an unset bit in the + * mask will be passed on the window below @window. + * + * An input shape is typically used with RGBA windows. + * The alpha channel of the window defines which pixels are + * invisible and allows for nicely antialiased borders, + * and the input shape controls where the window is + * "clickable". + * + * On the X11 platform, this requires version 1.1 of the + * shape extension. + * + * On the Win32 platform, this functionality is not present and the + * function does nothing. + * + * Since: 2.10 + */ +void +gdk_window_input_shape_combine_mask (GdkWindow *window, + GdkBitmap *mask, + gint x, + gint y) { GdkWindowObject *private; + GdkRegion *region; g_return_if_fail (GDK_IS_WINDOW (window)); private = (GdkWindowObject *) window; - GDK_WINDOW_IMPL_GET_IFACE (private->impl)->merge_child_shapes (window); + if (mask) + region = _gdk_windowing_get_shape_for_mask (mask); + else + region = NULL; + + gdk_window_input_shape_combine_region (window, + region, + x, y); + + if (region != NULL) + gdk_region_destroy (region); +} + +/** + * gdk_window_input_shape_combine_region: + * @window: a #GdkWindow + * @shape_region: region of window to be non-transparent + * @offset_x: X position of @shape_region in @window coordinates + * @offset_y: Y position of @shape_region in @window coordinates + * + * Like gdk_window_shape_combine_region(), but the shape applies + * only to event handling. Mouse events which happen while + * the pointer position corresponds to an unset bit in the + * mask will be passed on the window below @window. + * + * An input shape is typically used with RGBA windows. + * The alpha channel of the window defines which pixels are + * invisible and allows for nicely antialiased borders, + * and the input shape controls where the window is + * "clickable". + * + * On the X11 platform, this requires version 1.1 of the + * shape extension. + * + * On the Win32 platform, this functionality is not present and the + * function does nothing. + * + * Since: 2.10 + */ +void +gdk_window_input_shape_combine_region (GdkWindow *window, + const GdkRegion *shape_region, + gint offset_x, + gint offset_y) +{ + GdkWindowObject *private; + GdkWindowImplIface *impl_iface; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + private = (GdkWindowObject *) window; + + if (GDK_WINDOW_DESTROYED (window)) + return; + + if (private->input_shape) + gdk_region_destroy (private->input_shape); + + if (shape_region) + { + private->input_shape = gdk_region_copy (shape_region); + gdk_region_offset (private->input_shape, offset_x, offset_y); + } + else + private->input_shape = NULL; + + if (gdk_window_has_impl (private)) + { + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + impl_iface->input_shape_combine_region (window, private->input_shape, 0, 0); + } + + /* Pointer may have e.g. moved outside window due to the input mask change */ + _gdk_synthesize_crossing_events_for_geometry_change (window); +} + +static void +do_child_input_shapes (GdkWindow *window, + gboolean merge) +{ + GdkWindowObject *private; + GdkRectangle r; + GdkRegion *region; + + private = (GdkWindowObject *) window; + + r.x = 0; + r.y = 0; + r.width = private->width; + r.height = private->height; + + region = gdk_region_rectangle (&r); + remove_child_area (private, NULL, TRUE, region); + + if (merge && private->shape) + gdk_region_subtract (region, private->shape); + if (merge && private->input_shape) + gdk_region_subtract (region, private->input_shape); + + gdk_window_input_shape_combine_region (window, region, 0, 0); +} + + +/** + * gdk_window_set_child_input_shapes: + * @window: a #GdkWindow + * + * Sets the input shape mask of @window to the union of input shape masks + * for all children of @window, ignoring the input shape mask of @window + * itself. Contrast with gdk_window_merge_child_input_shapes() which includes + * the input shape mask of @window in the masks to be merged. + * + * Since: 2.10 + **/ +void +gdk_window_set_child_input_shapes (GdkWindow *window) +{ + g_return_if_fail (GDK_IS_WINDOW (window)); + + do_child_input_shapes (window, FALSE); +} + +/** + * gdk_window_merge_child_input_shapes: + * @window: a #GdkWindow + * + * Merges the input shape masks for any child windows into the + * input shape mask for @window. i.e. the union of all input masks + * for @window and its children will become the new input mask + * for @window. See gdk_window_input_shape_combine_mask(). + * + * This function is distinct from gdk_window_set_child_input_shapes() + * because it includes @window's input shape mask in the set of + * shapes to be merged. + * + * Since: 2.10 + **/ +void +gdk_window_merge_child_input_shapes (GdkWindow *window) +{ + g_return_if_fail (GDK_IS_WINDOW (window)); + + do_child_input_shapes (window, TRUE); } @@ -4123,12 +8337,19 @@ gdk_window_set_static_gravities (GdkWindow *window, gboolean use_static) { GdkWindowObject *private; + GdkWindowImplIface *impl_iface; g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE); private = (GdkWindowObject *) window; - return GDK_WINDOW_IMPL_GET_IFACE (private->impl)->set_static_gravities (window, use_static); + if (gdk_window_has_impl (private)) + { + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + return impl_iface->set_static_gravities (window, use_static); + } + + return FALSE; } /** @@ -4136,10 +8357,10 @@ gdk_window_set_static_gravities (GdkWindow *window, * @window: a #GdkWindow * @composited: %TRUE to set the window as composited * - * Sets a #GdkWindow as composited, or unsets it. Composited - * windows do not automatically have their contents drawn to - * the screen. Drawing is redirected to an offscreen buffer - * and an expose event is emitted on the parent of the composited + * Sets a #GdkWindow as composited, or unsets it. Composited + * windows do not automatically have their contents drawn to + * the screen. Drawing is redirected to an offscreen buffer + * and an expose event is emitted on the parent of the composited * window. It is the responsibility of the parent's expose handler * to manually merge the off-screen content onto the screen in * whatever way it sees fit. See @@ -4155,7 +8376,7 @@ gdk_window_set_static_gravities (GdkWindow *window, * window are also no longer clipped by the child. * * This call is only supported on some systems (currently, - * only X11 with new enough Xcomposite and Xdamage extensions). + * only X11 with new enough Xcomposite and Xdamage extensions). * You must call gdk_display_supports_composite() to check if * setting a window as composited is supported before * attempting to do so. @@ -4164,7 +8385,7 @@ gdk_window_set_static_gravities (GdkWindow *window, */ void gdk_window_set_composited (GdkWindow *window, - gboolean composited) + gboolean composited) { GdkWindowObject *private = (GdkWindowObject *)window; GdkDisplay *display; @@ -4176,6 +8397,9 @@ gdk_window_set_composited (GdkWindow *window, if (private->composited == composited) return; + if (composited) + gdk_window_ensure_native (window); + display = gdk_drawable_get_display (GDK_DRAWABLE (window)); if (!gdk_display_supports_composite (display) && composited) @@ -4187,13 +8411,18 @@ gdk_window_set_composited (GdkWindow *window, _gdk_windowing_window_set_composited (window, composited); + recompute_visible_regions (private, TRUE, FALSE); + + if (GDK_WINDOW_IS_MAPPED (window)) + gdk_window_invalidate_in_parent (private); + private->composited = composited; } static void remove_redirect_from_children (GdkWindowObject *private, - GdkWindowRedirect *redirect) + GdkWindowRedirect *redirect) { GList *l; GdkWindowObject *child; @@ -4240,7 +8469,7 @@ gdk_window_remove_redirection (GdkWindow *window) static void apply_redirect_to_children (GdkWindowObject *private, - GdkWindowRedirect *redirect) + GdkWindowRedirect *redirect) { GList *l; GdkWindowObject *child; @@ -4266,8 +8495,8 @@ apply_redirect_to_children (GdkWindowObject *private, * @src_y: y position in @window * @dest_x: x position in @drawable * @dest_y: y position in @drawable - * @width: width of redirection - * @height: height of redirection + * @width: width of redirection, or -1 to use the width of @window + * @height: height of redirection or -1 to use the height of @window * * Redirects drawing into @window so that drawing to the * window in the rectangle specified by @src_x, @src_y, @@ -4287,14 +8516,14 @@ void gdk_window_redirect_to_drawable (GdkWindow *window, GdkDrawable *drawable, gint src_x, - gint src_y, + gint src_y, gint dest_x, - gint dest_y, + gint dest_y, gint width, - gint height) + gint height) { GdkWindowObject *private; - + g_return_if_fail (GDK_IS_WINDOW (window)); g_return_if_fail (GDK_IS_DRAWABLE (drawable)); g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_ROOT); @@ -4313,7 +8542,7 @@ gdk_window_redirect_to_drawable (GdkWindow *window, if (height == -1) height = h; } - + private->redirect = g_new0 (GdkWindowRedirect, 1); private->redirect->redirected = private; private->redirect->pixmap = g_object_ref (drawable); @@ -4329,22 +8558,24 @@ gdk_window_redirect_to_drawable (GdkWindow *window, static void window_get_size_rectangle (GdkWindow *window, - GdkRectangle *rect) + GdkRectangle *rect) { + GdkWindowObject *private = (GdkWindowObject *) window; + rect->x = rect->y = 0; - gdk_drawable_get_size (GDK_DRAWABLE (window), &rect->width, &rect->height); + rect->width = private->width; + rect->height = private->height; } /* Calculates the real clipping region for a window, in window coordinates, * taking into account other windows, gc clip region and gc clip mask. */ -static GdkRegion * +GdkRegion * _gdk_window_calculate_full_clip_region (GdkWindow *window, GdkWindow *base_window, - GdkGC *gc, - gboolean do_children, - gint *base_x_offset, - gint *base_y_offset) + gboolean do_children, + gint *base_x_offset, + gint *base_y_offset) { GdkWindowObject *private = GDK_WINDOW_OBJECT (window); GdkRectangle visible_rect; @@ -4356,19 +8587,12 @@ _gdk_window_calculate_full_clip_region (GdkWindow *window, *base_x_offset = 0; if (base_y_offset) *base_y_offset = 0; - - if (!GDK_WINDOW_IS_MAPPED (window) || private->input_only) + + if (!private->viewable || private->input_only) return gdk_region_new (); window_get_size_rectangle (window, &visible_rect); - /* windows that a redirection has ben setup for need to be considered - * fully visible, in order to avoid missing redirected paint ops - * anywhere in the window area. - */ - if (private->redirect && private->redirect->redirected == private) - return gdk_region_rectangle (&visible_rect); - /* real_clip_region is in window coordinates */ real_clip_region = gdk_region_rectangle (&visible_rect); @@ -4379,35 +8603,43 @@ _gdk_window_calculate_full_clip_region (GdkWindow *window, parentwin = lastwin; else parentwin = lastwin->parent; - + /* Remove the areas of all overlapping windows above parentwin in the hiearachy */ - for (; parentwin != NULL && (parentwin == private || lastwin != (GdkWindowObject *)base_window); + for (; parentwin != NULL && + (parentwin == private || lastwin != (GdkWindowObject*) base_window); lastwin = parentwin, parentwin = lastwin->parent) { GList *cur; GdkRectangle real_clip_rect; - + if (parentwin != private) { x_offset += GDK_WINDOW_OBJECT (lastwin)->x; y_offset += GDK_WINDOW_OBJECT (lastwin)->y; } - + /* children is ordered in reverse stack order */ - for (cur = GDK_WINDOW_OBJECT (parentwin)->children; cur && cur->data != lastwin; cur = cur->next) + for (cur = parentwin->children; + cur && cur->data != lastwin; + cur = cur->next) { GdkWindow *child = cur->data; GdkWindowObject *child_private = (GdkWindowObject *)child; - + if (!GDK_WINDOW_IS_MAPPED (child) || child_private->input_only) continue; - window_get_size_rectangle (child, &visible_rect); + /* Ignore offscreen children, as they don't draw in their parent and + * don't take part in the clipping */ + if (gdk_window_is_offscreen (child_private)) + continue; + + window_get_size_rectangle (child, &visible_rect); /* Convert rect to "window" coords */ visible_rect.x += child_private->x - x_offset; visible_rect.y += child_private->y - y_offset; - + /* This shortcut is really necessary for performance when there are a lot of windows */ gdk_region_get_clipbox (real_clip_region, &real_clip_rect); if (visible_rect.x >= real_clip_rect.x + real_clip_rect.width || @@ -4415,41 +8647,23 @@ _gdk_window_calculate_full_clip_region (GdkWindow *window, visible_rect.y >= real_clip_rect.y + real_clip_rect.height || visible_rect.y + visible_rect.height <= real_clip_rect.y) continue; - + tmpreg = gdk_region_rectangle (&visible_rect); gdk_region_subtract (real_clip_region, tmpreg); gdk_region_destroy (tmpreg); } - + /* Clip to the parent */ window_get_size_rectangle ((GdkWindow *)parentwin, &visible_rect); /* Convert rect to "window" coords */ visible_rect.x += - x_offset; visible_rect.y += - y_offset; - + tmpreg = gdk_region_rectangle (&visible_rect); gdk_region_intersect (real_clip_region, tmpreg); gdk_region_destroy (tmpreg); } - if (gc) - { - GdkRegion *clip_region = _gdk_gc_get_clip_region (gc); - - if (clip_region) - { - /* clip_region is relative to gc clip origin which is relative to the window */ - /* offset it to window relative: */ - tmpreg = gdk_region_copy (clip_region); - gdk_region_offset (real_clip_region, - gc->clip_x_origin, - gc->clip_y_origin); - /* Intersect it with window hierarchy cliprect: */ - gdk_region_intersect (real_clip_region, tmpreg); - gdk_region_destroy (tmpreg); - } - } - if (base_x_offset) *base_x_offset = x_offset; if (base_y_offset) @@ -4458,9 +8672,9 @@ _gdk_window_calculate_full_clip_region (GdkWindow *window, return real_clip_region; } -static void -gdk_window_add_damage (GdkWindow *toplevel, - GdkRegion *damaged_region) +void +_gdk_window_add_damage (GdkWindow *toplevel, + GdkRegion *damaged_region) { GdkDisplay *display; GdkEvent event = { 0, }; @@ -4473,76 +8687,6 @@ gdk_window_add_damage (GdkWindow *toplevel, _gdk_event_queue_append (display, gdk_event_copy (&event)); } -static void -setup_redirect_clip (GdkWindow *window, - GdkGC *gc, - GdkWindowClipData *data) -{ - GdkWindowObject *private = (GdkWindowObject *)window; - GdkRegion *visible_region; - GdkRectangle dest_rect; - GdkRegion *tmpreg; - GdkWindow *toplevel; - - data->old_region = _gdk_gc_get_clip_region (gc); - if (data->old_region) - data->old_region = gdk_region_copy (data->old_region); - - data->old_clip_x_origin = gc->clip_x_origin; - data->old_clip_y_origin = gc->clip_y_origin; - - toplevel = GDK_WINDOW (private->redirect->redirected); - - /* Get the clip region for gc clip rect + window hierarchy in - window relative coords */ - visible_region = - _gdk_window_calculate_full_clip_region (window, toplevel, - gc, TRUE, - &data->x_offset, - &data->y_offset); - - /* Compensate for the source pos/size */ - data->x_offset -= private->redirect->src_x; - data->y_offset -= private->redirect->src_y; - dest_rect.x = -data->x_offset; - dest_rect.y = -data->y_offset; - dest_rect.width = private->redirect->width; - dest_rect.height = private->redirect->height; - tmpreg = gdk_region_rectangle (&dest_rect); - gdk_region_intersect (visible_region, tmpreg); - gdk_region_destroy (tmpreg); - - /* Compensate for the dest pos */ - data->x_offset += private->redirect->dest_x; - data->y_offset += private->redirect->dest_y; - - gdk_gc_set_clip_region (gc, visible_region); /* This resets clip origin! */ - - /* offset clip and tiles from window coords to pixmaps coords */ - gdk_gc_offset (gc, -data->x_offset, -data->y_offset); - - /* Offset region to abs coords and add to damage */ - gdk_region_offset (visible_region, data->x_offset, data->y_offset); - gdk_window_add_damage (toplevel, visible_region); - - gdk_region_destroy (visible_region); -} - -static void -reset_redirect_clip (GdkWindow *offscreen, - GdkGC *gc, - GdkWindowClipData *data) -{ - /* offset back */ - gdk_gc_offset (gc, data->x_offset, data->y_offset); - - /* reset old clip */ - gdk_gc_set_clip_region (gc, data->old_region); - if (data->old_region) - gdk_region_destroy (data->old_region); - gdk_gc_set_clip_origin (gc, data->old_clip_x_origin, data->old_clip_y_origin); -} - static void gdk_window_redirect_free (GdkWindowRedirect *redirect) { @@ -4550,5 +8694,1751 @@ gdk_window_redirect_free (GdkWindowRedirect *redirect) g_free (redirect); } +/* Gets the toplevel for a window as used for events, + i.e. including offscreen parents */ +static GdkWindowObject * +get_event_parent (GdkWindowObject *window) +{ + if (window->window_type == GDK_WINDOW_OFFSCREEN) + return (GdkWindowObject *)gdk_offscreen_window_get_embedder ((GdkWindow *)window); + else + return window->parent; +} + +/* Gets the toplevel for a window as used for events, + i.e. including offscreen parents going up to the native + toplevel */ +static GdkWindow * +get_event_toplevel (GdkWindow *w) +{ + GdkWindowObject *private = GDK_WINDOW_OBJECT (w); + GdkWindowObject *parent; + + while ((parent = get_event_parent (private)) != NULL && + (parent->window_type != GDK_WINDOW_ROOT)) + private = parent; + + return GDK_WINDOW (private); +} + +gboolean +_gdk_window_event_parent_of (GdkWindow *parent, + GdkWindow *child) +{ + GdkWindow *w; + + w = child; + while (w != NULL) + { + if (w == parent) + return TRUE; + + w = (GdkWindow *)get_event_parent ((GdkWindowObject *)w); + } + + return FALSE; +} + +static void +update_cursor (GdkDisplay *display) +{ + GdkWindowObject *cursor_window, *parent, *toplevel; + GdkWindow *pointer_window; + GdkWindowImplIface *impl_iface; + GdkPointerGrabInfo *grab; + + pointer_window = display->pointer_info.window_under_pointer; + + /* We ignore the serials here and just pick the last grab + we've sent, as that would shortly be used anyway. */ + grab = _gdk_display_get_last_pointer_grab (display); + if (/* have grab */ + grab != NULL && + /* the pointer is not in a descendant of the grab window */ + !_gdk_window_event_parent_of (grab->window, pointer_window)) + /* use the cursor from the grab window */ + cursor_window = (GdkWindowObject *)grab->window; + else + /* otherwise use the cursor from the pointer window */ + cursor_window = (GdkWindowObject *)pointer_window; + + /* Find the first window with the cursor actually set, as + the cursor is inherited from the parent */ + while (cursor_window->cursor == NULL && + (parent = get_event_parent (cursor_window)) != NULL && + parent->window_type != GDK_WINDOW_ROOT) + cursor_window = parent; + + /* Set all cursors on toplevel, otherwise its tricky to keep track of + * which native window has what cursor set. */ + toplevel = (GdkWindowObject *)get_event_toplevel (pointer_window); + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (toplevel->impl); + impl_iface->set_cursor ((GdkWindow *)toplevel, cursor_window->cursor); +} + +static void +from_embedder (GdkWindowObject *window, + gdouble embedder_x, + gdouble embedder_y, + gdouble *offscreen_x, + gdouble *offscreen_y) +{ + g_signal_emit (window, + signals[FROM_EMBEDDER], 0, + embedder_x, embedder_y, + offscreen_x, offscreen_y, + NULL); +} + +static void +convert_coords_to_child (GdkWindowObject *child, + gdouble x, + gdouble y, + gdouble *child_x, + gdouble *child_y) +{ + if (gdk_window_is_offscreen (child)) + { + from_embedder (child, x, y, + child_x, child_y); + } + else + { + *child_x = x - child->x; + *child_y = y - child->y; + } +} + +static gboolean +point_in_window (GdkWindowObject *window, + gdouble x, + gdouble y) +{ + return + x >= 0 && x < window->width && + y >= 0 && y < window->height && + (window->shape == NULL || + gdk_region_point_in (window->shape, + x, y)) && + (window->input_shape == NULL || + gdk_region_point_in (window->input_shape, + x, y)); +} + +static GdkWindow * +convert_native_coords_to_toplevel (GdkWindow *window, + gdouble child_x, + gdouble child_y, + gdouble *toplevel_x, + gdouble *toplevel_y) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + gdouble x, y; + + x = child_x; + y = child_y; + + while (!gdk_window_is_toplevel (private)) + { + x += private->x; + y += private->y; + private = private->parent; + } + + *toplevel_x = x; + *toplevel_y = y; + + return (GdkWindow *)private; +} + +static void +convert_toplevel_coords_to_window (GdkWindow *window, + gdouble toplevel_x, + gdouble toplevel_y, + gdouble *window_x, + gdouble *window_y) +{ + GdkWindowObject *private; + GdkWindowObject *parent; + gdouble x, y; + GList *children, *l; + + private = GDK_WINDOW_OBJECT (window); + + x = toplevel_x; + y = toplevel_y; + + children = NULL; + while ((parent = get_event_parent (private)) != NULL && + (parent->window_type != GDK_WINDOW_ROOT)) + { + children = g_list_prepend (children, private); + private = parent; + } + + for (l = children; l != NULL; l = l->next) + convert_coords_to_child (l->data, x, y, &x, &y); + + g_list_free (children); + + *window_x = x; + *window_y = y; +} + +static GdkWindowObject * +pick_embedded_child (GdkWindowObject *window, + gdouble x, + gdouble y) +{ + GdkWindowObject *res; + + res = NULL; + g_signal_emit (window, + signals[PICK_EMBEDDED_CHILD], 0, + x, y, &res); + + return res; +} + +GdkWindow * +_gdk_window_find_child_at (GdkWindow *window, + int x, + int y) +{ + GdkWindowObject *private, *sub; + double child_x, child_y; + GList *l; + + private = (GdkWindowObject *)window; + + if (point_in_window (private, x, y)) + { + /* Children is ordered in reverse stack order, i.e. first is topmost */ + for (l = private->children; l != NULL; l = l->next) + { + sub = l->data; + + if (!GDK_WINDOW_IS_MAPPED (sub)) + continue; + + convert_coords_to_child (sub, + x, y, + &child_x, &child_y); + if (point_in_window (sub, child_x, child_y)) + return (GdkWindow *)sub; + } + + if (private->num_offscreen_children > 0) + { + sub = pick_embedded_child (private, + x, y); + if (sub) + return (GdkWindow *)sub; + } + } + + return NULL; +} + +GdkWindow * +_gdk_window_find_descendant_at (GdkWindow *toplevel, + gdouble x, + gdouble y, + gdouble *found_x, + gdouble *found_y) +{ + GdkWindowObject *private, *sub; + gdouble child_x, child_y; + GList *l; + gboolean found; + + private = (GdkWindowObject *)toplevel; + + if (point_in_window (private, x, y)) + { + do + { + found = FALSE; + /* Children is ordered in reverse stack order, i.e. first is topmost */ + for (l = private->children; l != NULL; l = l->next) + { + sub = l->data; + + if (!GDK_WINDOW_IS_MAPPED (sub)) + continue; + + convert_coords_to_child (sub, + x, y, + &child_x, &child_y); + if (point_in_window (sub, child_x, child_y)) + { + x = child_x; + y = child_y; + private = sub; + found = TRUE; + break; + } + } + if (!found && + private->num_offscreen_children > 0) + { + sub = pick_embedded_child (private, + x, y); + if (sub) + { + found = TRUE; + private = sub; + from_embedder (sub, x, y, &x, &y); + } + } + } + while (found); + } + else + { + /* Not in window at all */ + private = NULL; + } + + if (found_x) + *found_x = x; + if (found_y) + *found_y = y; + + return (GdkWindow *)private; +} + +/** + * gdk_window_beep: + * @window: a toplevel #GdkWindow + * + * Emits a short beep associated to @window in the appropriate + * display, if supported. Otherwise, emits a short beep on + * the display just as gdk_display_beep(). + * + * Since: 2.12 + **/ +void +gdk_window_beep (GdkWindow *window) +{ + GdkDisplay *display; + GdkWindow *toplevel; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + if (GDK_WINDOW_DESTROYED (window)) + return; + + toplevel = get_event_toplevel (window); + display = gdk_drawable_get_display (GDK_DRAWABLE (window)); + + if (toplevel && !gdk_window_is_offscreen ((GdkWindowObject *)toplevel)) + _gdk_windowing_window_beep (toplevel); + else + gdk_display_beep (display); +} + +static const guint type_masks[] = { + GDK_SUBSTRUCTURE_MASK, /* GDK_DELETE = 0 */ + GDK_STRUCTURE_MASK, /* GDK_DESTROY = 1 */ + GDK_EXPOSURE_MASK, /* GDK_EXPOSE = 2 */ + GDK_POINTER_MOTION_MASK, /* GDK_MOTION_NOTIFY = 3 */ + GDK_BUTTON_PRESS_MASK, /* GDK_BUTTON_PRESS = 4 */ + GDK_BUTTON_PRESS_MASK, /* GDK_2BUTTON_PRESS = 5 */ + GDK_BUTTON_PRESS_MASK, /* GDK_3BUTTON_PRESS = 6 */ + GDK_BUTTON_RELEASE_MASK, /* GDK_BUTTON_RELEASE = 7 */ + GDK_KEY_PRESS_MASK, /* GDK_KEY_PRESS = 8 */ + GDK_KEY_RELEASE_MASK, /* GDK_KEY_RELEASE = 9 */ + GDK_ENTER_NOTIFY_MASK, /* GDK_ENTER_NOTIFY = 10 */ + GDK_LEAVE_NOTIFY_MASK, /* GDK_LEAVE_NOTIFY = 11 */ + GDK_FOCUS_CHANGE_MASK, /* GDK_FOCUS_CHANGE = 12 */ + GDK_STRUCTURE_MASK, /* GDK_CONFIGURE = 13 */ + GDK_VISIBILITY_NOTIFY_MASK, /* GDK_MAP = 14 */ + GDK_VISIBILITY_NOTIFY_MASK, /* GDK_UNMAP = 15 */ + GDK_PROPERTY_CHANGE_MASK, /* GDK_PROPERTY_NOTIFY = 16 */ + GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_CLEAR = 17 */ + GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_REQUEST = 18 */ + GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_NOTIFY = 19 */ + GDK_PROXIMITY_IN_MASK, /* GDK_PROXIMITY_IN = 20 */ + GDK_PROXIMITY_OUT_MASK, /* GDK_PROXIMITY_OUT = 21 */ + GDK_ALL_EVENTS_MASK, /* GDK_DRAG_ENTER = 22 */ + GDK_ALL_EVENTS_MASK, /* GDK_DRAG_LEAVE = 23 */ + GDK_ALL_EVENTS_MASK, /* GDK_DRAG_MOTION = 24 */ + GDK_ALL_EVENTS_MASK, /* GDK_DRAG_STATUS = 25 */ + GDK_ALL_EVENTS_MASK, /* GDK_DROP_START = 26 */ + GDK_ALL_EVENTS_MASK, /* GDK_DROP_FINISHED = 27 */ + GDK_ALL_EVENTS_MASK, /* GDK_CLIENT_EVENT = 28 */ + GDK_VISIBILITY_NOTIFY_MASK, /* GDK_VISIBILITY_NOTIFY = 29 */ + GDK_EXPOSURE_MASK, /* GDK_NO_EXPOSE = 30 */ + GDK_SCROLL_MASK | GDK_BUTTON_PRESS_MASK,/* GDK_SCROLL= 31 */ + 0, /* GDK_WINDOW_STATE = 32 */ + 0, /* GDK_SETTING = 33 */ + 0, /* GDK_OWNER_CHANGE = 34 */ + 0, /* GDK_GRAB_BROKEN = 35 */ + 0, /* GDK_DAMAGE = 36 */ +}; +G_STATIC_ASSERT (G_N_ELEMENTS (type_masks) == GDK_EVENT_LAST); + +/* send motion events if the right buttons are down */ +static guint +update_evmask_for_button_motion (guint evmask, + GdkModifierType mask) +{ + if (evmask & GDK_BUTTON_MOTION_MASK && + mask & (GDK_BUTTON1_MASK | + GDK_BUTTON2_MASK | + GDK_BUTTON3_MASK | + GDK_BUTTON4_MASK | + GDK_BUTTON5_MASK)) + evmask |= GDK_POINTER_MOTION_MASK; + + if ((evmask & GDK_BUTTON1_MOTION_MASK && mask & GDK_BUTTON1_MASK) || + (evmask & GDK_BUTTON2_MOTION_MASK && mask & GDK_BUTTON2_MASK) || + (evmask & GDK_BUTTON3_MOTION_MASK && mask & GDK_BUTTON3_MASK)) + evmask |= GDK_POINTER_MOTION_MASK; + + return evmask; +} + +static gboolean +is_button_type (GdkEventType type) +{ + return type == GDK_BUTTON_PRESS || + type == GDK_2BUTTON_PRESS || + type == GDK_3BUTTON_PRESS || + type == GDK_BUTTON_RELEASE || + type == GDK_SCROLL; +} + +static gboolean +is_motion_type (GdkEventType type) +{ + return type == GDK_MOTION_NOTIFY || + type == GDK_ENTER_NOTIFY || + type == GDK_LEAVE_NOTIFY; +} + +static GdkWindowObject * +find_common_ancestor (GdkWindowObject *win1, + GdkWindowObject *win2) +{ + GdkWindowObject *tmp; + GList *path1 = NULL, *path2 = NULL; + GList *list1, *list2; + + tmp = win1; + while (tmp != NULL && tmp->window_type != GDK_WINDOW_ROOT) + { + path1 = g_list_prepend (path1, tmp); + tmp = get_event_parent (tmp); + } + + tmp = win2; + while (tmp != NULL && tmp->window_type != GDK_WINDOW_ROOT) + { + path2 = g_list_prepend (path2, tmp); + tmp = get_event_parent (tmp); + } + + list1 = path1; + list2 = path2; + tmp = NULL; + while (list1 && list2 && (list1->data == list2->data)) + { + tmp = (GdkWindowObject *)list1->data; + list1 = g_list_next (list1); + list2 = g_list_next (list2); + } + g_list_free (path1); + g_list_free (path2); + + return tmp; +} + +GdkEvent * +_gdk_make_event (GdkWindow *window, + GdkEventType type, + GdkEvent *event_in_queue, + gboolean before_event) +{ + GdkEvent *event = gdk_event_new (type); + guint32 the_time; + GdkModifierType the_state; + + the_time = gdk_event_get_time (event_in_queue); + gdk_event_get_state (event_in_queue, &the_state); + + event->any.window = g_object_ref (window); + event->any.send_event = FALSE; + if (event_in_queue && event_in_queue->any.send_event) + event->any.send_event = TRUE; + + switch (type) + { + case GDK_MOTION_NOTIFY: + event->motion.time = the_time; + event->motion.axes = NULL; + event->motion.state = the_state; + break; + + case GDK_BUTTON_PRESS: + case GDK_2BUTTON_PRESS: + case GDK_3BUTTON_PRESS: + case GDK_BUTTON_RELEASE: + event->button.time = the_time; + event->button.axes = NULL; + event->button.state = the_state; + break; + + case GDK_SCROLL: + event->scroll.time = the_time; + event->scroll.state = the_state; + break; + + case GDK_KEY_PRESS: + case GDK_KEY_RELEASE: + event->key.time = the_time; + event->key.state = the_state; + break; + + case GDK_ENTER_NOTIFY: + case GDK_LEAVE_NOTIFY: + event->crossing.time = the_time; + event->crossing.state = the_state; + break; + + case GDK_PROPERTY_NOTIFY: + event->property.time = the_time; + event->property.state = the_state; + break; + + case GDK_SELECTION_CLEAR: + case GDK_SELECTION_REQUEST: + case GDK_SELECTION_NOTIFY: + event->selection.time = the_time; + break; + + case GDK_PROXIMITY_IN: + case GDK_PROXIMITY_OUT: + event->proximity.time = the_time; + break; + + case GDK_DRAG_ENTER: + case GDK_DRAG_LEAVE: + case GDK_DRAG_MOTION: + case GDK_DRAG_STATUS: + case GDK_DROP_START: + case GDK_DROP_FINISHED: + event->dnd.time = the_time; + break; + + case GDK_FOCUS_CHANGE: + case GDK_CONFIGURE: + case GDK_MAP: + case GDK_UNMAP: + case GDK_CLIENT_EVENT: + case GDK_VISIBILITY_NOTIFY: + case GDK_NO_EXPOSE: + case GDK_DELETE: + case GDK_DESTROY: + case GDK_EXPOSE: + default: + break; + } + + if (event_in_queue) + { + if (before_event) + _gdk_event_queue_insert_before (gdk_drawable_get_display (window), event_in_queue, event); + else + _gdk_event_queue_insert_after (gdk_drawable_get_display (window), event_in_queue, event); + } + else + _gdk_event_queue_append (gdk_drawable_get_display (window), event); + + return event; +} + +static void +send_crossing_event (GdkDisplay *display, + GdkWindowObject *toplevel, + GdkWindowObject *window, + GdkEventType type, + GdkCrossingMode mode, + GdkNotifyType notify_type, + GdkWindow *subwindow, + gint toplevel_x, + gint toplevel_y, + GdkModifierType mask, + guint32 time_, + GdkEvent *event_in_queue, + gulong serial) +{ + GdkEvent *event; + guint32 window_event_mask, type_event_mask; + GdkPointerGrabInfo *grab; + GdkWindowImplIface *impl_iface; + + grab = _gdk_display_has_pointer_grab (display, serial); + + if (grab != NULL && + !grab->owner_events) + { + /* !owner_event => only report events wrt grab window, ignore rest */ + if ((GdkWindow *)window != grab->window) + return; + window_event_mask = grab->event_mask; + } + else + window_event_mask = window->event_mask; + + if (type == GDK_LEAVE_NOTIFY) + type_event_mask = GDK_LEAVE_NOTIFY_MASK; + else + type_event_mask = GDK_ENTER_NOTIFY_MASK; + + if (window->extension_events != 0) + { + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (window->impl); + impl_iface->input_window_crossing ((GdkWindow *)window, + type == GDK_ENTER_NOTIFY); + } + + if (window_event_mask & type_event_mask) + { + event = _gdk_make_event ((GdkWindow *)window, type, event_in_queue, TRUE); + event->crossing.time = time_; + event->crossing.subwindow = subwindow; + if (subwindow) + g_object_ref (subwindow); + convert_toplevel_coords_to_window ((GdkWindow *)window, + toplevel_x, toplevel_y, + &event->crossing.x, &event->crossing.y); + event->crossing.x_root = toplevel_x + toplevel->x; + event->crossing.y_root = toplevel_y + toplevel->y; + event->crossing.mode = mode; + event->crossing.detail = notify_type; + event->crossing.focus = FALSE; + event->crossing.state = mask; + } +} + + +/* The coordinates are in the toplevel window that src/dest are in. + * src and dest are always (if != NULL) in the same toplevel, as + * we get a leave-notify and set the window_under_pointer to null + * before crossing to another toplevel. + */ +void +_gdk_synthesize_crossing_events (GdkDisplay *display, + GdkWindow *src, + GdkWindow *dest, + GdkCrossingMode mode, + gint toplevel_x, + gint toplevel_y, + GdkModifierType mask, + guint32 time_, + GdkEvent *event_in_queue, + gulong serial, + gboolean non_linear) +{ + GdkWindowObject *c; + GdkWindowObject *win, *last, *next; + GList *path, *list; + GdkWindowObject *a; + GdkWindowObject *b; + GdkWindowObject *toplevel; + GdkNotifyType notify_type; + + /* TODO: Don't send events to toplevel, as we get those from the windowing system */ + + a = (GdkWindowObject *)src; + b = (GdkWindowObject *)dest; + if (a == b) + return; /* No crossings generated between src and dest */ + + c = find_common_ancestor (a, b); + + non_linear |= (c != a) && (c != b); + + if (a) /* There might not be a source (i.e. if no previous pointer_in_window) */ + { + toplevel = (GdkWindowObject *)gdk_window_get_toplevel ((GdkWindow *)a); + + /* Traverse up from a to (excluding) c sending leave events */ + if (non_linear) + notify_type = GDK_NOTIFY_NONLINEAR; + else if (c == a) + notify_type = GDK_NOTIFY_INFERIOR; + else + notify_type = GDK_NOTIFY_ANCESTOR; + send_crossing_event (display, toplevel, + a, GDK_LEAVE_NOTIFY, + mode, + notify_type, + NULL, + toplevel_x, toplevel_y, + mask, time_, + event_in_queue, + serial); + + if (c != a) + { + if (non_linear) + notify_type = GDK_NOTIFY_NONLINEAR_VIRTUAL; + else + notify_type = GDK_NOTIFY_VIRTUAL; + + last = a; + win = get_event_parent (a); + while (win != c && win->window_type != GDK_WINDOW_ROOT) + { + send_crossing_event (display, toplevel, + win, GDK_LEAVE_NOTIFY, + mode, + notify_type, + (GdkWindow *)last, + toplevel_x, toplevel_y, + mask, time_, + event_in_queue, + serial); + + last = win; + win = get_event_parent (win); + } + } + } + + if (b) /* Might not be a dest, e.g. if we're moving out of the window */ + { + toplevel = (GdkWindowObject *)gdk_window_get_toplevel ((GdkWindow *)b); + + /* Traverse down from c to b */ + if (c != b) + { + path = NULL; + win = get_event_parent (b); + while (win != c && win->window_type != GDK_WINDOW_ROOT) + { + path = g_list_prepend (path, win); + win = get_event_parent (win); + } + + if (non_linear) + notify_type = GDK_NOTIFY_NONLINEAR_VIRTUAL; + else + notify_type = GDK_NOTIFY_VIRTUAL; + + list = path; + while (list) + { + win = (GdkWindowObject *)list->data; + list = g_list_next (list); + if (list) + next = (GdkWindowObject *)list->data; + else + next = b; + + send_crossing_event (display, toplevel, + win, GDK_ENTER_NOTIFY, + mode, + notify_type, + (GdkWindow *)next, + toplevel_x, toplevel_y, + mask, time_, + event_in_queue, + serial); + } + g_list_free (path); + } + + + if (non_linear) + notify_type = GDK_NOTIFY_NONLINEAR; + else if (c == a) + notify_type = GDK_NOTIFY_ANCESTOR; + else + notify_type = GDK_NOTIFY_INFERIOR; + + send_crossing_event (display, toplevel, + b, GDK_ENTER_NOTIFY, + mode, + notify_type, + NULL, + toplevel_x, toplevel_y, + mask, time_, + event_in_queue, + serial); + } +} + +/* Returns the window inside the event window with the pointer in it + * at the specified coordinates, or NULL if its not in any child of + * the toplevel. It also takes into account !owner_events grabs. + */ +static GdkWindow * +get_pointer_window (GdkDisplay *display, + GdkWindow *event_window, + gdouble toplevel_x, + gdouble toplevel_y, + gulong serial) +{ + GdkWindow *pointer_window; + GdkPointerGrabInfo *grab; + + if (event_window == display->pointer_info.toplevel_under_pointer) + pointer_window = + _gdk_window_find_descendant_at (event_window, + toplevel_x, toplevel_y, + NULL, NULL); + else + pointer_window = NULL; + + grab = _gdk_display_has_pointer_grab (display, serial); + if (grab != NULL && + !grab->owner_events && + pointer_window != grab->window) + pointer_window = NULL; + + return pointer_window; +} + +void +_gdk_display_set_window_under_pointer (GdkDisplay *display, + GdkWindow *window) +{ + /* We don't track this if all native, and it can cause issues + with the update_cursor call below */ + if (_gdk_native_windows) + return; + + if (display->pointer_info.window_under_pointer) + g_object_unref (display->pointer_info.window_under_pointer); + display->pointer_info.window_under_pointer = window; + if (window) + g_object_ref (window); + + if (window) + update_cursor (display); + + _gdk_display_enable_motion_hints (display); +} + +/* + *-------------------------------------------------------------- + * gdk_pointer_grab + * + * Grabs the pointer to a specific window + * + * Arguments: + * "window" is the window which will receive the grab + * "owner_events" specifies whether events will be reported as is, + * or relative to "window" + * "event_mask" masks only interesting events + * "confine_to" limits the cursor movement to the specified window + * "cursor" changes the cursor for the duration of the grab + * "time" specifies the time + * + * Results: + * + * Side effects: + * requires a corresponding call to gdk_pointer_ungrab + * + *-------------------------------------------------------------- + */ +GdkGrabStatus +gdk_pointer_grab (GdkWindow * window, + gboolean owner_events, + GdkEventMask event_mask, + GdkWindow * confine_to, + GdkCursor * cursor, + guint32 time) +{ + GdkWindow *native; + GdkDisplay *display; + GdkGrabStatus res; + gulong serial; + + g_return_val_if_fail (window != NULL, 0); + g_return_val_if_fail (GDK_IS_WINDOW (window), 0); + g_return_val_if_fail (confine_to == NULL || GDK_IS_WINDOW (confine_to), 0); + + /* We need a native window for confine to to work, ensure we have one */ + if (confine_to) + { + if (!gdk_window_ensure_native (confine_to)) + { + g_warning ("Can't confine to grabbed window, not native"); + confine_to = NULL; + } + } + + /* Non-viewable client side window => fail */ + if (!_gdk_window_has_impl (window) && + !gdk_window_is_viewable (window)) + return GDK_GRAB_NOT_VIEWABLE; + + if (_gdk_native_windows) + native = window; + else + native = gdk_window_get_toplevel (window); + while (gdk_window_is_offscreen ((GdkWindowObject *)native)) + { + native = gdk_offscreen_window_get_embedder (native); + + if (native == NULL || + (!_gdk_window_has_impl (native) && + !gdk_window_is_viewable (native))) + return GDK_GRAB_NOT_VIEWABLE; + + native = gdk_window_get_toplevel (native); + } + + display = gdk_drawable_get_display (window); + + serial = _gdk_windowing_window_get_next_serial (display); + + res = _gdk_windowing_pointer_grab (window, + native, + owner_events, + get_native_grab_event_mask (event_mask), + confine_to, + cursor, + time); + + if (res == GDK_GRAB_SUCCESS) + _gdk_display_add_pointer_grab (display, + window, + native, + owner_events, + event_mask, + serial, + time, + FALSE); + + return res; +} + +/** + * gdk_window_geometry_changed: + * @window: an embedded offscreen #GdkWindow + * + * This function informs GDK that the geometry of an embedded + * offscreen window has changed. This is necessary for GDK to keep + * track of which offscreen window the pointer is in. + * + * Since: 2.18 + */ +void +gdk_window_geometry_changed (GdkWindow *window) +{ + _gdk_synthesize_crossing_events_for_geometry_change (window); +} + +static gboolean +do_synthesize_crossing_event (gpointer data) +{ + GdkDisplay *display; + GdkWindow *changed_toplevel; + GdkWindowObject *changed_toplevel_priv; + GdkWindow *new_window_under_pointer; + gulong serial; + + changed_toplevel = data; + changed_toplevel_priv = (GdkWindowObject *)changed_toplevel; + + changed_toplevel_priv->synthesize_crossing_event_queued = FALSE; + + if (GDK_WINDOW_DESTROYED (changed_toplevel)) + return FALSE; + + display = gdk_drawable_get_display (changed_toplevel); + serial = _gdk_windowing_window_get_next_serial (display); + + if (changed_toplevel == display->pointer_info.toplevel_under_pointer) + { + new_window_under_pointer = + get_pointer_window (display, changed_toplevel, + display->pointer_info.toplevel_x, + display->pointer_info.toplevel_y, + serial); + if (new_window_under_pointer != + display->pointer_info.window_under_pointer) + { + _gdk_synthesize_crossing_events (display, + display->pointer_info.window_under_pointer, + new_window_under_pointer, + GDK_CROSSING_NORMAL, + display->pointer_info.toplevel_x, + display->pointer_info.toplevel_y, + display->pointer_info.state, + GDK_CURRENT_TIME, + NULL, + serial, + FALSE); + _gdk_display_set_window_under_pointer (display, new_window_under_pointer); + } + } + + return FALSE; +} + +void +_gdk_synthesize_crossing_events_for_geometry_change (GdkWindow *changed_window) +{ + GdkDisplay *display; + GdkWindow *toplevel; + GdkWindowObject *toplevel_priv; + + if (_gdk_native_windows) + return; /* We use the native crossing events if all native */ + + display = gdk_drawable_get_display (changed_window); + + toplevel = get_event_toplevel (changed_window); + toplevel_priv = (GdkWindowObject *)toplevel; + + if (toplevel == display->pointer_info.toplevel_under_pointer && + !toplevel_priv->synthesize_crossing_event_queued) + { + toplevel_priv->synthesize_crossing_event_queued = TRUE; + g_idle_add_full (GDK_PRIORITY_EVENTS - 1, + do_synthesize_crossing_event, + g_object_ref (toplevel), + g_object_unref); + } +} + +/* Don't use for crossing events */ +static GdkWindow * +get_event_window (GdkDisplay *display, + GdkWindow *pointer_window, + GdkEventType type, + GdkModifierType mask, + guint *evmask_out, + gulong serial) +{ + guint evmask; + GdkWindow *grab_window; + GdkWindowObject *w; + GdkPointerGrabInfo *grab; + + grab = _gdk_display_has_pointer_grab (display, serial); + + if (grab != NULL && !grab->owner_events) + { + evmask = grab->event_mask; + evmask = update_evmask_for_button_motion (evmask, mask); + + grab_window = grab->window; + + if (evmask & type_masks[type]) + { + if (evmask_out) + *evmask_out = evmask; + return grab_window; + } + else + return NULL; + } + + w = (GdkWindowObject *)pointer_window; + while (w != NULL) + { + evmask = w->event_mask; + evmask = update_evmask_for_button_motion (evmask, mask); + + if (evmask & type_masks[type]) + { + if (evmask_out) + *evmask_out = evmask; + return (GdkWindow *)w; + } + + w = get_event_parent (w); + } + + if (grab != NULL && + grab->owner_events) + { + evmask = grab->event_mask; + evmask = update_evmask_for_button_motion (evmask, mask); + + if (evmask & type_masks[type]) + { + if (evmask_out) + *evmask_out = evmask; + return grab->window; + } + else + return NULL; + } + + return NULL; +} + +static gboolean +proxy_pointer_event (GdkDisplay *display, + GdkEvent *source_event, + gulong serial) +{ + GdkWindow *toplevel_window, *event_window; + GdkWindow *pointer_window; + GdkEvent *event; + guint state; + gdouble toplevel_x, toplevel_y; + guint32 time_; + gboolean non_linear; + + event_window = source_event->any.window; + gdk_event_get_coords (source_event, &toplevel_x, &toplevel_y); + gdk_event_get_state (source_event, &state); + time_ = gdk_event_get_time (source_event); + toplevel_window = convert_native_coords_to_toplevel (event_window, + toplevel_x, toplevel_y, + &toplevel_x, &toplevel_y); + + non_linear = FALSE; + if ((source_event->type == GDK_LEAVE_NOTIFY || + source_event->type == GDK_ENTER_NOTIFY) && + (source_event->crossing.detail == GDK_NOTIFY_NONLINEAR || + source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL)) + non_linear = TRUE; + + /* If we get crossing events with subwindow unexpectedly being NULL + that means there is a native subwindow that gdk doesn't know about. + We track these and forward them, with the correct virtual window + events inbetween. + This is important to get right, as metacity uses gdk for the frame + windows, but gdk doesn't know about the client windows reparented + into the frame. */ + if (((source_event->type == GDK_LEAVE_NOTIFY && + source_event->crossing.detail == GDK_NOTIFY_INFERIOR) || + (source_event->type == GDK_ENTER_NOTIFY && + (source_event->crossing.detail == GDK_NOTIFY_VIRTUAL || + source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))) && + source_event->crossing.subwindow == NULL) + { + /* Left for an unknown (to gdk) subwindow */ + + /* Send leave events from window under pointer to event window + that will get the subwindow == NULL window */ + _gdk_synthesize_crossing_events (display, + display->pointer_info.window_under_pointer, + event_window, + source_event->crossing.mode, + toplevel_x, toplevel_y, + state, time_, + source_event, + serial, + non_linear); + + /* Send subwindow == NULL event */ + send_crossing_event (display, + (GdkWindowObject *)toplevel_window, + (GdkWindowObject *)event_window, + source_event->type, + source_event->crossing.mode, + source_event->crossing.detail, + NULL, + toplevel_x, toplevel_y, + state, time_, + source_event, + serial); + + _gdk_display_set_window_under_pointer (display, NULL); + return TRUE; + } + + pointer_window = get_pointer_window (display, toplevel_window, + toplevel_x, toplevel_y, serial); + + if (((source_event->type == GDK_ENTER_NOTIFY && + source_event->crossing.detail == GDK_NOTIFY_INFERIOR) || + (source_event->type == GDK_LEAVE_NOTIFY && + (source_event->crossing.detail == GDK_NOTIFY_VIRTUAL || + source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))) && + source_event->crossing.subwindow == NULL) + { + /* Entered from an unknown (to gdk) subwindow */ + + /* Send subwindow == NULL event */ + send_crossing_event (display, + (GdkWindowObject *)toplevel_window, + (GdkWindowObject *)event_window, + source_event->type, + source_event->crossing.mode, + source_event->crossing.detail, + NULL, + toplevel_x, toplevel_y, + state, time_, + source_event, + serial); + + /* Send enter events from event window to pointer_window */ + _gdk_synthesize_crossing_events (display, + event_window, + pointer_window, + source_event->crossing.mode, + toplevel_x, toplevel_y, + state, time_, + source_event, + serial, non_linear); + _gdk_display_set_window_under_pointer (display, pointer_window); + return TRUE; + } + + if (display->pointer_info.window_under_pointer != pointer_window) + { + /* Either a toplevel crossing notify that ended up inside a child window, + or a motion notify that got into another child window */ + + /* Different than last time, send crossing events */ + _gdk_synthesize_crossing_events (display, + display->pointer_info.window_under_pointer, + pointer_window, + GDK_CROSSING_NORMAL, + toplevel_x, toplevel_y, + state, time_, + source_event, + serial, non_linear); + _gdk_display_set_window_under_pointer (display, pointer_window); + } + else if (source_event->type == GDK_MOTION_NOTIFY) + { + GdkWindow *event_win; + guint evmask; + gboolean is_hint; + + event_win = get_event_window (display, + pointer_window, + source_event->type, + state, + &evmask, + serial); + + is_hint = FALSE; + + if (event_win && + (evmask & GDK_POINTER_MOTION_HINT_MASK)) + { + if (display->pointer_info.motion_hint_serial != 0 && + serial < display->pointer_info.motion_hint_serial) + event_win = NULL; /* Ignore event */ + else + { + is_hint = TRUE; + display->pointer_info.motion_hint_serial = G_MAXULONG; + } + } + + if (event_win && !display->ignore_core_events) + { + event = _gdk_make_event (event_win, GDK_MOTION_NOTIFY, source_event, FALSE); + event->motion.time = time_; + convert_toplevel_coords_to_window (event_win, + toplevel_x, toplevel_y, + &event->motion.x, &event->motion.y); + event->motion.x_root = source_event->motion.x_root; + event->motion.y_root = source_event->motion.y_root;; + event->motion.state = state; + event->motion.is_hint = is_hint; + event->motion.device = NULL; + event->motion.device = source_event->motion.device; + } + } + + /* unlink all move events from queue. + We handle our own, including our emulated masks. */ + return TRUE; +} + +#define GDK_ANY_BUTTON_MASK (GDK_BUTTON1_MASK | \ + GDK_BUTTON2_MASK | \ + GDK_BUTTON3_MASK | \ + GDK_BUTTON4_MASK | \ + GDK_BUTTON5_MASK) + +static gboolean +proxy_button_event (GdkEvent *source_event, + gulong serial) +{ + GdkWindow *toplevel_window, *event_window; + GdkWindow *event_win; + GdkWindow *pointer_window; + GdkWindowObject *parent; + GdkEvent *event; + guint state; + guint32 time_; + GdkEventType type; + gdouble toplevel_x, toplevel_y; + GdkDisplay *display; + GdkWindowObject *w; + + type = source_event->any.type; + event_window = source_event->any.window; + gdk_event_get_coords (source_event, &toplevel_x, &toplevel_y); + gdk_event_get_state (source_event, &state); + time_ = gdk_event_get_time (source_event); + display = gdk_drawable_get_display (source_event->any.window); + toplevel_window = convert_native_coords_to_toplevel (event_window, + toplevel_x, toplevel_y, + &toplevel_x, &toplevel_y); + + if (type == GDK_BUTTON_PRESS && + !source_event->any.send_event && + _gdk_display_has_pointer_grab (display, serial) == NULL) + { + pointer_window = + _gdk_window_find_descendant_at (toplevel_window, + toplevel_x, toplevel_y, + NULL, NULL); + + /* Find the event window, that gets the grab */ + w = (GdkWindowObject *)pointer_window; + while (w != NULL && + (parent = get_event_parent (w)) != NULL && + parent->window_type != GDK_WINDOW_ROOT) + { + if (w->event_mask & GDK_BUTTON_PRESS_MASK) + break; + w = parent; + } + pointer_window = (GdkWindow *)w; + + _gdk_display_add_pointer_grab (display, + pointer_window, + toplevel_window, + FALSE, + gdk_window_get_events (pointer_window), + serial, + time_, + TRUE); + _gdk_display_pointer_grab_update (display, serial); + } + + pointer_window = get_pointer_window (display, toplevel_window, + toplevel_x, toplevel_y, + serial); + + event_win = get_event_window (display, + pointer_window, + type, state, + NULL, serial); + + if (event_win == NULL || display->ignore_core_events) + return TRUE; + + event = _gdk_make_event (event_win, type, source_event, FALSE); + + switch (type) + { + case GDK_BUTTON_PRESS: + case GDK_BUTTON_RELEASE: + event->button.button = source_event->button.button; + convert_toplevel_coords_to_window (event_win, + toplevel_x, toplevel_y, + &event->button.x, &event->button.y); + event->button.x_root = source_event->button.x_root; + event->button.y_root = source_event->button.y_root; + event->button.state = state; + event->button.device = source_event->button.device; + + if (type == GDK_BUTTON_PRESS) + _gdk_event_button_generate (display, event); + return TRUE; + + case GDK_SCROLL: + event->scroll.direction = source_event->scroll.direction; + convert_toplevel_coords_to_window (event_win, + toplevel_x, toplevel_y, + &event->scroll.x, &event->scroll.y); + event->scroll.x_root = source_event->scroll.x_root; + event->scroll.y_root = source_event->scroll.y_root; + event->scroll.state = state; + event->scroll.device = source_event->scroll.device; + return TRUE; + + default: + return FALSE; + } + + return TRUE; /* Always unlink original, we want to obey the emulated event mask */ +} + +#ifdef DEBUG_WINDOW_PRINTING +static void +gdk_window_print (GdkWindowObject *window, + int indent) +{ + GdkRectangle r; + const char *window_types[] = { + "root", + "toplevel", + "child", + "dialog", + "temp", + "foreign", + "offscreen" + }; + + g_print ("%*s%p: [%s] %d,%d %dx%d", indent, "", window, + window->user_data ? g_type_name_from_instance (window->user_data) : "no widget", + window->x, window->y, + window->width, window->height + ); + + if (gdk_window_has_impl (window)) + { +#ifdef GDK_WINDOWING_X11 + g_print (" impl(0x%lx)", gdk_x11_drawable_get_xid (GDK_DRAWABLE (window))); +#endif + } + + if (window->window_type != GDK_WINDOW_CHILD) + g_print (" %s", window_types[window->window_type]); + + if (window->input_only) + g_print (" input-only"); + + if (window->shaped) + g_print (" shaped"); + + if (!gdk_window_is_visible ((GdkWindow *)window)) + g_print (" hidden"); + + g_print (" abs[%d,%d]", + window->abs_x, window->abs_y); + + gdk_region_get_clipbox (window->clip_region, &r); + if (gdk_region_empty (window->clip_region)) + g_print (" clipbox[empty]"); + else + g_print (" clipbox[%d,%d %dx%d]", r.x, r.y, r.width, r.height); + + g_print ("\n"); +} + + +static void +gdk_window_print_tree (GdkWindow *window, + int indent, + gboolean include_input_only) +{ + GdkWindowObject *private; + GList *l; + + private = (GdkWindowObject *)window; + + if (private->input_only && !include_input_only) + return; + + gdk_window_print (private, indent); + + for (l = private->children; l != NULL; l = l->next) + gdk_window_print_tree (l->data, indent + 4, include_input_only); +} + +#endif /* DEBUG_WINDOW_PRINTING */ + +static gboolean +is_input_event (GdkDisplay *display, + GdkEvent *event) +{ + GdkDevice *core_pointer; + + core_pointer = gdk_display_get_core_pointer (display); + if ((event->type == GDK_MOTION_NOTIFY && + event->motion.device != core_pointer) || + ((event->type == GDK_BUTTON_PRESS || + event->type == GDK_BUTTON_RELEASE) && + event->button.device != core_pointer)) + return TRUE; + return FALSE; +} + +void +_gdk_windowing_got_event (GdkDisplay *display, + GList *event_link, + GdkEvent *event, + gulong serial) +{ + GdkWindow *event_window; + GdkWindowObject *event_private; + gdouble x, y; + gboolean unlink_event; + guint old_state, old_button; + GdkPointerGrabInfo *button_release_grab; + gboolean is_toplevel; + + if (gdk_event_get_time (event) != GDK_CURRENT_TIME) + display->last_event_time = gdk_event_get_time (event); + + _gdk_display_pointer_grab_update (display, + serial); + + event_window = event->any.window; + if (!event_window) + return; + + event_private = GDK_WINDOW_OBJECT (event_window); + +#ifdef DEBUG_WINDOW_PRINTING + if (event->type == GDK_KEY_PRESS && + (event->key.keyval == 0xa7 || + event->key.keyval == 0xbd)) + { + gdk_window_print_tree (event_window, 0, + event->key.keyval == 0xbd); + } +#endif + + if (_gdk_native_windows) + { + if (event->type == GDK_BUTTON_PRESS && + !event->any.send_event && + _gdk_display_has_pointer_grab (display, serial) == NULL) + { + _gdk_display_add_pointer_grab (display, + event_window, + event_window, + FALSE, + gdk_window_get_events (event_window), + serial, + gdk_event_get_time (event), + TRUE); + _gdk_display_pointer_grab_update (display, + serial); + } + if (event->type == GDK_BUTTON_RELEASE && + !event->any.send_event) + { + button_release_grab = + _gdk_display_has_pointer_grab (display, serial); + if (button_release_grab && + button_release_grab->implicit && + (event->button.state & GDK_ANY_BUTTON_MASK & ~(GDK_BUTTON1_MASK << (event->button.button - 1))) == 0) + { + button_release_grab->serial_end = serial; + button_release_grab->implicit_ungrab = FALSE; + _gdk_display_pointer_grab_update (display, serial); + } + } + + if (event->type == GDK_BUTTON_PRESS) + _gdk_event_button_generate (display, event); + + return; + } + + if (event->type == GDK_VISIBILITY_NOTIFY) + { + event_private->native_visibility = event->visibility.state; + gdk_window_update_visibility_recursively (event_private, + event_private); + return; + } + + if (is_input_event (display, event)) + return; + + if (!(is_button_type (event->type) || + is_motion_type (event->type)) || + event_private->window_type == GDK_WINDOW_ROOT) + return; + + is_toplevel = gdk_window_is_toplevel (event_private); + + if ((event->type == GDK_ENTER_NOTIFY || + event->type == GDK_LEAVE_NOTIFY) && + (event->crossing.mode == GDK_CROSSING_GRAB || + event->crossing.mode == GDK_CROSSING_UNGRAB) && + (_gdk_display_has_pointer_grab (display, serial) || + event->crossing.detail == GDK_NOTIFY_INFERIOR)) + { + /* We synthesize all crossing events due to grabs ourselves, + * so we ignore the native ones caused by our native pointer_grab + * calls. Otherwise we would proxy these crossing event and cause + * multiple copies of crossing events for grabs. + * + * We do want to handle grabs from other clients though, as for + * instance alt-tab in metacity causes grabs like these and + * we want to handle those. Thus the has_pointer_grab check. + * + * Implicit grabs on child windows create some grabbing events + * that are sent before the button press. This means we can't + * detect these with the has_pointer_grab check (as the implicit + * grab is only noticed when we get button press event), so we + * detect these events by checking for INFERIOR enter or leave + * events. These should never be a problem to filter out. + */ + + /* We ended up in this window after some (perhaps other clients) + grab, so update the toplevel_under_window state */ + if (is_toplevel && + event->type == GDK_ENTER_NOTIFY && + event->crossing.mode == GDK_CROSSING_UNGRAB) + { + if (display->pointer_info.toplevel_under_pointer) + g_object_unref (display->pointer_info.toplevel_under_pointer); + display->pointer_info.toplevel_under_pointer = g_object_ref (event_window); + } + + unlink_event = TRUE; + goto out; + } + + /* Track toplevel_under_pointer */ + if (is_toplevel) + { + if (event->type == GDK_ENTER_NOTIFY && + event->crossing.detail != GDK_NOTIFY_INFERIOR) + { + if (display->pointer_info.toplevel_under_pointer) + g_object_unref (display->pointer_info.toplevel_under_pointer); + display->pointer_info.toplevel_under_pointer = g_object_ref (event_window); + } + else if (event->type == GDK_LEAVE_NOTIFY && + event->crossing.detail != GDK_NOTIFY_INFERIOR && + display->pointer_info.toplevel_under_pointer == event_window) + { + if (display->pointer_info.toplevel_under_pointer) + g_object_unref (display->pointer_info.toplevel_under_pointer); + display->pointer_info.toplevel_under_pointer = NULL; + } + } + + /* Store last pointer window and position/state */ + old_state = display->pointer_info.state; + old_button = display->pointer_info.button; + + gdk_event_get_coords (event, &x, &y); + convert_native_coords_to_toplevel (event_window, x, y, &x, &y); + display->pointer_info.toplevel_x = x; + display->pointer_info.toplevel_y = y; + gdk_event_get_state (event, &display->pointer_info.state); + if (event->type == GDK_BUTTON_PRESS || + event->type == GDK_BUTTON_RELEASE) + display->pointer_info.button = event->button.button; + + if (display->pointer_info.state != old_state || + display->pointer_info.button != old_button) + _gdk_display_enable_motion_hints (display); + + unlink_event = FALSE; + if (is_motion_type (event->type)) + unlink_event = proxy_pointer_event (display, + event, + serial); + else if (is_button_type (event->type)) + unlink_event = proxy_button_event (event, + serial); + + if (event->type == GDK_BUTTON_RELEASE && + !event->any.send_event) + { + button_release_grab = + _gdk_display_has_pointer_grab (display, serial); + if (button_release_grab && + button_release_grab->implicit && + (event->button.state & GDK_ANY_BUTTON_MASK & ~(GDK_BUTTON1_MASK << (event->button.button - 1))) == 0) + { + button_release_grab->serial_end = serial; + button_release_grab->implicit_ungrab = FALSE; + _gdk_display_pointer_grab_update (display, serial); + } + } + + out: + if (unlink_event) + { + _gdk_event_queue_remove_link (display, event_link); + g_list_free_1 (event_link); + gdk_event_free (event); + } +} + + +static GdkWindow * +get_extension_event_window (GdkDisplay *display, + GdkWindow *pointer_window, + GdkEventType type, + gulong serial) +{ + guint evmask; + GdkWindow *grab_window; + GdkWindowObject *w; + GdkPointerGrabInfo *grab; + + grab = _gdk_display_has_pointer_grab (display, serial); + + if (grab != NULL && !grab->owner_events) + { + evmask = grab->event_mask; + + grab_window = grab->window; + + if (evmask & type_masks[type]) + return grab_window; + else + return NULL; + } + + w = (GdkWindowObject *)pointer_window; + while (w != NULL) + { + evmask = w->extension_events; + + if (evmask & type_masks[type]) + return (GdkWindow *)w; + + w = get_event_parent (w); + } + + if (grab != NULL && + grab->owner_events) + { + evmask = grab->event_mask; + + if (evmask & type_masks[type]) + return grab->window; + else + return NULL; + } + + return NULL; +} + + +GdkWindow * +_gdk_window_get_input_window_for_event (GdkWindow *native_window, + GdkEventType event_type, + int x, int y, + gulong serial) +{ + GdkDisplay *display; + GdkWindow *toplevel_window; + GdkWindow *pointer_window; + GdkWindow *event_win; + gdouble toplevel_x, toplevel_y; + + toplevel_x = x; + toplevel_y = y; + + display = gdk_drawable_get_display (native_window); + toplevel_window = convert_native_coords_to_toplevel (native_window, + toplevel_x, toplevel_y, + &toplevel_x, &toplevel_y); + pointer_window = get_pointer_window (display, toplevel_window, + toplevel_x, toplevel_y, serial); + event_win = get_extension_event_window (display, + pointer_window, + event_type, + serial); + + return event_win; +} + + #define __GDK_WINDOW_C__ #include "gdkaliasdef.c" diff --git a/gdk/gdkwindow.h b/gdk/gdkwindow.h index 866bb69467..b8502754b8 100644 --- a/gdk/gdkwindow.h +++ b/gdk/gdkwindow.h @@ -37,10 +37,10 @@ G_BEGIN_DECLS -typedef struct _GdkGeometry GdkGeometry; -typedef struct _GdkWindowAttr GdkWindowAttr; -typedef struct _GdkPointerHooks GdkPointerHooks; -typedef struct _GdkWindowRedirect GdkWindowRedirect; +typedef struct _GdkGeometry GdkGeometry; +typedef struct _GdkWindowAttr GdkWindowAttr; +typedef struct _GdkPointerHooks GdkPointerHooks; +typedef struct _GdkWindowRedirect GdkWindowRedirect; /* Classes of windows. * InputOutput: Almost every window should be of this type. Such windows @@ -77,7 +77,8 @@ typedef enum GDK_WINDOW_CHILD, GDK_WINDOW_DIALOG, GDK_WINDOW_TEMP, - GDK_WINDOW_FOREIGN + GDK_WINDOW_FOREIGN, + GDK_WINDOW_OFFSCREEN } GdkWindowType; /* Window attribute mask values. @@ -257,8 +258,17 @@ typedef struct _GdkWindowObjectClass GdkWindowObjectClass; #define GDK_IS_WINDOW(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WINDOW)) #define GDK_IS_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_WINDOW)) #define GDK_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_WINDOW, GdkWindowObjectClass)) + +#ifndef GDK_DISABLE_DEPRECATED #define GDK_WINDOW_OBJECT(object) ((GdkWindowObject *) GDK_WINDOW (object)) +#ifndef GDK_COMPILATION + +/* We used to export all of GdkWindowObject, but we don't want to keep doing so. + However, there are various parts of it accessed by macros and other code, + so we keep the old exported version public, but in reality it is larger. */ + +/**** DON'T CHANGE THIS STRUCT, the real version is in gdkinternals.h ****/ struct _GdkWindowObject { GdkDrawable parent_instance; @@ -308,6 +318,8 @@ struct _GdkWindowObject GdkWindowRedirect *redirect; }; +#endif +#endif struct _GdkWindowObjectClass { @@ -322,6 +334,7 @@ GdkWindow* gdk_window_new (GdkWindow *parent, gint attributes_mask); void gdk_window_destroy (GdkWindow *window); GdkWindowType gdk_window_get_window_type (GdkWindow *window); +gboolean gdk_window_is_destroyed (GdkWindow *window); GdkWindow* gdk_window_at_pointer (gint *win_x, gint *win_y); void gdk_window_show (GdkWindow *window); @@ -356,6 +369,9 @@ void gdk_window_clear_area_e (GdkWindow *window, gint height); void gdk_window_raise (GdkWindow *window); void gdk_window_lower (GdkWindow *window); +void gdk_window_restack (GdkWindow *window, + GdkWindow *sibling, + gboolean above); void gdk_window_focus (GdkWindow *window, guint32 timestamp); void gdk_window_set_user_data (GdkWindow *window, @@ -379,6 +395,7 @@ void gdk_window_move_region (GdkWindow *window, const GdkRegion *region, gint dx, gint dy); +gboolean gdk_window_ensure_native (GdkWindow *window); /* * This allows for making shaped (partially transparent) windows @@ -492,6 +509,7 @@ void gdk_window_begin_paint_rect (GdkWindow *window, void gdk_window_begin_paint_region (GdkWindow *window, const GdkRegion *region); void gdk_window_end_paint (GdkWindow *window); +void gdk_window_flush (GdkWindow *window); void gdk_window_set_title (GdkWindow *window, const gchar *title); @@ -508,6 +526,7 @@ void gdk_window_set_back_pixmap (GdkWindow *window, gboolean parent_relative); void gdk_window_set_cursor (GdkWindow *window, GdkCursor *cursor); +GdkCursor *gdk_window_get_cursor (GdkWindow *window); void gdk_window_get_user_data (GdkWindow *window, gpointer *data); void gdk_window_get_geometry (GdkWindow *window, @@ -522,8 +541,13 @@ void gdk_window_get_position (GdkWindow *window, gint gdk_window_get_origin (GdkWindow *window, gint *x, gint *y); +void gdk_window_get_root_coords (GdkWindow *window, + gint x, + gint y, + gint *root_x, + gint *root_y); -#if !defined (GDK_DISABLE_DEPRECATED) || defined (GTK_COMPILATION) +#if !defined (GDK_DISABLE_DEPRECATED) || defined (GTK_COMPILATION) || defined (GDK_COMPILATION) /* Used by gtk_handle_box_button_changed () */ gboolean gdk_window_get_deskrelative_origin (GdkWindow *window, gint *x, @@ -645,12 +669,22 @@ GdkPointerHooks *gdk_set_pointer_hooks (const GdkPointerHooks *new_hooks); GdkWindow *gdk_get_default_root_window (void); -void gdk_window_redirect_to_drawable (GdkWindow *window, - GdkDrawable *drawable, - gint src_x, gint src_y, - gint dest_x, gint dest_y, - gint width, gint height); -void gdk_window_remove_redirection (GdkWindow *window); +/* Offscreen redirection */ +GdkPixmap *gdk_offscreen_window_get_pixmap (GdkWindow *window); +void gdk_offscreen_window_set_embedder (GdkWindow *window, + GdkWindow *embedder); +GdkWindow *gdk_offscreen_window_get_embedder (GdkWindow *window); +void gdk_window_geometry_changed (GdkWindow *window); + +void gdk_window_redirect_to_drawable (GdkWindow *window, + GdkDrawable *drawable, + gint src_x, + gint src_y, + gint dest_x, + gint dest_y, + gint width, + gint height); +void gdk_window_remove_redirection (GdkWindow *window); #ifndef GDK_DISABLE_DEPRECATED #define GDK_ROOT_PARENT() (gdk_get_default_root_window ()) diff --git a/gdk/gdkwindowimpl.h b/gdk/gdkwindowimpl.h index f9f97b6fa0..00f2f1b13d 100644 --- a/gdk/gdkwindowimpl.h +++ b/gdk/gdkwindowimpl.h @@ -44,11 +44,16 @@ struct _GdkWindowImplIface GTypeInterface g_iface; void (* show) (GdkWindow *window, - gboolean raise); + gboolean already_mapped); void (* hide) (GdkWindow *window); void (* withdraw) (GdkWindow *window); void (* raise) (GdkWindow *window); void (* lower) (GdkWindow *window); + void (* restack_under) (GdkWindow *window, + GList *native_siblings); + void (* restack_toplevel) (GdkWindow *window, + GdkWindow *sibling, + gboolean above); void (* move_resize) (GdkWindow *window, gboolean with_move, @@ -56,25 +61,10 @@ struct _GdkWindowImplIface gint y, gint width, gint height); - void (* move_region) (GdkWindow *window, - const GdkRegion *region, - gint dx, - gint dy); - void (* scroll) (GdkWindow *window, - gint dx, - gint dy); - - void (* clear_area) (GdkWindow *window, - gint x, - gint y, - gint width, - gint height, - gboolean send_expose); void (* set_background) (GdkWindow *window, const GdkColor *color); void (* set_back_pixmap) (GdkWindow *window, - GdkPixmap *pixmap, - gboolean parent_relative); + GdkPixmap *pixmap); GdkEventMask (* get_events) (GdkWindow *window); void (* set_events) (GdkWindow *window, @@ -84,6 +74,9 @@ struct _GdkWindowImplIface GdkWindow *new_parent, gint x, gint y); + void (* clear_region) (GdkWindow *window, + GdkRegion *region, + gboolean send_expose); void (* set_cursor) (GdkWindow *window, GdkCursor *cursor); @@ -94,31 +87,88 @@ struct _GdkWindowImplIface gint *width, gint *height, gint *depth); - gint (* get_origin) (GdkWindow *window, + gint (* get_root_coords) (GdkWindow *window, + gint x, + gint y, + gint *root_x, + gint *root_y); + gint (* get_deskrelative_origin) (GdkWindow *window, gint *x, gint *y); - void (* get_offsets) (GdkWindow *window, - gint *x_offset, - gint *y_offset); + gboolean (* get_pointer) (GdkWindow *window, + gint *x, + gint *y, + GdkModifierType *mask); - void (* shape_combine_mask) (GdkWindow *window, - GdkBitmap *mask, - gint x, - gint y); void (* shape_combine_region) (GdkWindow *window, const GdkRegion *shape_region, gint offset_x, gint offset_y); - void (* set_child_shapes) (GdkWindow *window); - void (* merge_child_shapes) (GdkWindow *window); + void (* input_shape_combine_region) (GdkWindow *window, + const GdkRegion *shape_region, + gint offset_x, + gint offset_y); gboolean (* set_static_gravities) (GdkWindow *window, gboolean use_static); + + /* Called before processing updates for a window. This gives the windowing + * layer a chance to save the region for later use in avoiding duplicate + * exposes. The return value indicates whether the function has a saved + * the region; if the result is TRUE, then the windowing layer is responsible + * for destroying the region later. + */ + gboolean (* queue_antiexpose) (GdkWindow *window, + GdkRegion *update_area); + void (* queue_translation) (GdkWindow *window, + GdkGC *gc, + GdkRegion *area, + gint dx, + gint dy); + +/* Called to do the windowing system specific part of gdk_window_destroy(), + * + * window: The window being destroyed + * recursing: If TRUE, then this is being called because a parent + * was destroyed. This generally means that the call to the windowing system + * to destroy the window can be omitted, since it will be destroyed as a result + * of the parent being destroyed. Unless @foreign_destroy + * + * foreign_destroy: If TRUE, the window or a parent was destroyed by some external + * agency. The window has already been destroyed and no windowing + * system calls should be made. (This may never happen for some + * windowing systems.) + */ + void (* destroy) (GdkWindow *window, + gboolean recursing, + gboolean foreign_destroy); + + void (* input_window_destroy) (GdkWindow *window); + void (* input_window_crossing)(GdkWindow *window, + gboolean enter); }; /* Interface Functions */ GType gdk_window_impl_get_type (void) G_GNUC_CONST; +/* private definitions from gdkwindow.h */ + +struct _GdkWindowRedirect +{ + GdkWindowObject *redirected; + GdkDrawable *pixmap; + + gint src_x; + gint src_y; + gint dest_x; + gint dest_y; + gint width; + gint height; + + GdkRegion *damage; + guint damage_idle; +}; + G_END_DECLS #endif /* __GDK_WINDOW_IMPL_H__ */ diff --git a/gdk/makefile.msc b/gdk/makefile.msc index 35e6467237..ded0aa277d 100644 --- a/gdk/makefile.msc +++ b/gdk/makefile.msc @@ -18,22 +18,6 @@ WTKIT = $(TOP)\wtkit126 ############################################################### # Nothing much configurable below - -!IFNDEF DEBUG -# Full optimization: -OPTIMIZE = -Ox -MD -Zi -LINKDEBUG = /nodefaultlib:libc.lib -!ELSE -# Debugging: -OPTIMIZE = -Zi -MDd -LINKDEBUG = /nodefaultlib:libcd.lib /nodefaultlib:libc.lib /debug -!ENDIF - -# cl -? describes the options -CC = cl -G5 -GF $(OPTIMIZE) -W3 -nologo - -LDFLAGS = /link $(LINKDEBUG) - # overwrite version? GTK_VER=2.0 GDK_PIXBUF_VER=$(GTK_VER) @@ -42,17 +26,21 @@ GDK_PIXBUF_VER=$(GTK_VER) PERL = perl !ENDIF -CFLAGS = -FImsvc_recommended_pragmas.h -I . -I .. \ +INCLUDES = -FImsvc_recommended_pragmas.h \ + -I . -I .. \ $(GLIB_CFLAGS) $(PANGO_CFLAGS) $(CAIRO_CFLAGS) -I ../gdk-pixbuf \ - $(G_DEBUGGING) -DHAVE_CONFIG_H -DGDK_ENABLE_BROKEN \ + +DEFINES = \ + -DHAVE_CONFIG_H -DGDK_ENABLE_BROKEN \ -DGDK_VERSION=\"$(GTK_VER)\" \ - -DG_LOG_DOMAIN=\"Gdk\" + -DG_LOG_DOMAIN=\"Gdk\" \ + -DGDK_COMPILATION -DG_LOG_DOMAIN=\"Gdk\" EXTRALIBS = \ $(WTKIT)\lib\i386\wntab32x.lib \ $(GLIB_LIBS) \ ..\gdk-pixbuf\gdk_pixbuf-$(GDK_PIXBUF_VER).lib \ - $(PANGOWIN32_LIBS) $(INTL_LIBS) $(CAIRO_LIBS) \ + $(PANGOWIN32_LIBS) $(PANGOCAIRO_LIBS) $(INTL_LIBS) $(CAIRO_LIBS) \ $(PANGOCAIRO_LIBS) gdk-win32-backend : @@ -95,6 +83,8 @@ gdk_OBJECTS = \ gdkkeynames.obj \ gdkkeys.obj \ gdkkeyuni.obj \ + gdkmarshalers.obj \ + gdkoffscreenwindow.obj \ gdkpango.obj \ gdkpixbuf-drawable.obj \ gdkpixbuf-render.obj \ @@ -135,10 +125,10 @@ gdk_public_h_sources = \ # private marshalers gdkmarshalers.h : gdkmarshalers.list - $(GLIB)\gobject\glib-genmarshal --prefix=gdk_marshal gdkmarshalers.list --header >>gdkmarshalers.h + $(GLIB)\gobject\glib-genmarshal --prefix=_gdk_marshal gdkmarshalers.list --header >>gdkmarshalers.h gdkmarshalers.c : gdkmarshalers.list - $(GLIB)\gobject\glib-genmarshal --prefix=gdk_marshal gdkmarshalers.list --body >gdkmarshalers.c + $(GLIB)\gobject\glib-genmarshal --prefix=_gdk_marshal gdkmarshalers.list --body >gdkmarshalers.c gdkenumtypes.h: $(gdk_public_h_sources) gdkenumtypes.h.template $(PERL) $(GLIB)\gobject\glib-mkenums --template gdkenumtypes.h.template \ @@ -182,9 +172,6 @@ gdk-x11-$(GTK_VER).dll : $(gdk_OBJECTS) gdk.def x11\gdk-x11.lib testgdk.exe : libgdk-win32-$(GTK_VER)-0.dll testgdk.obj $(CC) -Fetestgdk.exe testgdk.obj gdk-win32-$(GTK_VER).lib $(EXTRALIBS) $(LDFLAGS) -.c.obj : - $(CC) $(CFLAGS) -GD -c -DGDK_COMPILATION -DG_LOG_DOMAIN=\"Gdk\" $< - clean:: cd win32 nmake -f makefile.msc clean diff --git a/gdk/quartz/GdkQuartzView.c b/gdk/quartz/GdkQuartzView.c index 3cc0f2e124..5d643eb984 100644 --- a/gdk/quartz/GdkQuartzView.c +++ b/gdk/quartz/GdkQuartzView.c @@ -35,6 +35,11 @@ return gdk_window; } +-(NSTrackingRectTag)trackingRect +{ + return trackingRect; +} + -(BOOL)isFlipped { return YES; @@ -67,46 +72,46 @@ if (NSEqualRects (rect, NSZeroRect)) return; - GDK_QUARTZ_ALLOC_POOL; + /* Clear our own bookkeeping of regions that need display */ + if (impl->needs_display_region) + { + gdk_region_destroy (impl->needs_display_region); + impl->needs_display_region = NULL; + } [self getRectsBeingDrawn:&drawn_rects count:&count]; - region = gdk_region_new (); - - for (i = 0; i < count; i++) + /* Note: arbitrary limit here to not degrade performace too much. It would + * be better to optimize the construction of the region below, by using + * _gdk_region_new_from_yxbanded_rects. + */ + if (count > 25) { - gdk_rect.x = drawn_rects[i].origin.x; - gdk_rect.y = drawn_rects[i].origin.y; - gdk_rect.width = drawn_rects[i].size.width; - gdk_rect.height = drawn_rects[i].size.height; - - gdk_region_union_with_rect (region, &gdk_rect); - } - - if (!gdk_region_empty (region)) - { - GdkEvent event; - gdk_rect.x = rect.origin.x; gdk_rect.y = rect.origin.y; gdk_rect.width = rect.size.width; gdk_rect.height = rect.size.height; - - event.expose.type = GDK_EXPOSE; - event.expose.window = g_object_ref (gdk_window); - event.expose.send_event = FALSE; - event.expose.count = 0; - event.expose.region = region; - event.expose.area = gdk_rect; - - impl->in_paint_rect_count++; - (*_gdk_event_func) (&event, _gdk_event_data); - - impl->in_paint_rect_count--; - - g_object_unref (gdk_window); + region = gdk_region_rectangle (&gdk_rect); } + else + { + region = gdk_region_new (); + + for (i = 0; i < count; i++) + { + gdk_rect.x = drawn_rects[i].origin.x; + gdk_rect.y = drawn_rects[i].origin.y; + gdk_rect.width = drawn_rects[i].size.width; + gdk_rect.height = drawn_rects[i].size.height; + + gdk_region_union_with_rect (region, &gdk_rect); + } + } + + impl->in_paint_rect_count++; + _gdk_window_process_updates_recurse (gdk_window, region); + impl->in_paint_rect_count--; gdk_region_destroy (region); @@ -115,8 +120,6 @@ [[self window] invalidateShadow]; needsInvalidateShadow = NO; } - - GDK_QUARTZ_RELEASE_POOL; } -(void)setNeedsInvalidateShadow:(BOOL)invalidate @@ -133,6 +136,9 @@ GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl); NSRect rect; + if (!impl->toplevel) + return; + if (trackingRect) { [self removeTrackingRect:trackingRect]; diff --git a/gdk/quartz/GdkQuartzView.h b/gdk/quartz/GdkQuartzView.h index 752c3989b3..f9c9a9cabe 100644 --- a/gdk/quartz/GdkQuartzView.h +++ b/gdk/quartz/GdkQuartzView.h @@ -29,6 +29,7 @@ -(void)setGdkWindow:(GdkWindow *)window; -(GdkWindow *)gdkWindow; +-(NSTrackingRectTag)trackingRect; -(void)setNeedsInvalidateShadow:(BOOL)invalidate; @end diff --git a/gdk/quartz/GdkQuartzWindow.c b/gdk/quartz/GdkQuartzWindow.c index 3f16815110..a974bdaee3 100644 --- a/gdk/quartz/GdkQuartzWindow.c +++ b/gdk/quartz/GdkQuartzWindow.c @@ -142,17 +142,8 @@ NSRect content_rect = [self contentRectForFrameRect:[self frame]]; GdkWindow *window = [[self contentView] gdkWindow]; GdkWindowObject *private = (GdkWindowObject *)window; - GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl); GdkEvent *event; - /* Ignore new position during showing/hiding the window, otherwise we - * would get the off-screen position that is used for hidden windows to - * get reliable MouseEntered events when showing them again. See comments - * in show() and hide(). - */ - if (inShowOrHide) - return; - private->x = content_rect.origin.x; private->y = _gdk_quartz_window_get_inverted_screen_y (content_rect.origin.y + content_rect.size.height); @@ -161,8 +152,8 @@ event->configure.window = g_object_ref (window); event->configure.x = private->x; event->configure.y = private->y; - event->configure.width = impl->width; - event->configure.height = impl->height; + event->configure.width = private->width; + event->configure.height = private->height; _gdk_event_queue_append (gdk_display_get_default (), event); } @@ -172,21 +163,22 @@ NSRect content_rect = [self contentRectForFrameRect:[self frame]]; GdkWindow *window = [[self contentView] gdkWindow]; GdkWindowObject *private = (GdkWindowObject *)window; - GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl); GdkEvent *event; - impl->width = content_rect.size.width; - impl->height = content_rect.size.height; + private->width = content_rect.size.width; + private->height = content_rect.size.height; - [[self contentView] setFrame:NSMakeRect (0, 0, impl->width, impl->height)]; + [[self contentView] setFrame:NSMakeRect (0, 0, private->width, private->height)]; + + _gdk_window_update_size (window); /* Synthesize a configure event */ event = gdk_event_new (GDK_CONFIGURE); event->configure.window = g_object_ref (window); event->configure.x = private->x; event->configure.y = private->y; - event->configure.width = impl->width; - event->configure.height = impl->height; + event->configure.width = private->width; + event->configure.height = private->height; _gdk_event_queue_append (gdk_display_get_default (), event); } @@ -279,32 +271,8 @@ GdkWindow *window = [[self contentView] gdkWindow]; GdkWindowObject *private = (GdkWindowObject *)window; GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl); - gboolean was_hidden; - int requested_x = 0, requested_y = 0; inShowOrHide = YES; - was_hidden = FALSE; - - if (!GDK_WINDOW_IS_MAPPED (window)) - { - NSRect content_rect; - NSRect frame_rect; - - was_hidden = TRUE; - - /* We move the window in place if it's not mapped. See comment in - * hide(). - */ - content_rect = - NSMakeRect (private->x, - _gdk_quartz_window_get_inverted_screen_y (private->y) - impl->height, - impl->width, impl->height); - frame_rect = [impl->toplevel frameRectForContentRect:content_rect]; - [impl->toplevel setFrame:frame_rect display:NO]; - - requested_x = frame_rect.origin.x; - requested_y = frame_rect.origin.y; - } if (makeKey) [impl->toplevel makeKeyAndOrderFront:impl->toplevel]; @@ -312,20 +280,6 @@ [impl->toplevel orderFront:nil]; inShowOrHide = NO; - - /* When the window manager didn't allow our request, update the position - * to what it really ended up as. - */ - if (was_hidden) - { - NSRect frame_rect; - - frame_rect = [impl->toplevel frame]; - if (requested_x != frame_rect.origin.x || requested_y != frame_rect.origin.y) - { - [self windowDidMove:nil]; - } - } } - (void)hide @@ -333,23 +287,9 @@ GdkWindow *window = [[self contentView] gdkWindow]; GdkWindowObject *private = (GdkWindowObject *)window; GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl); - NSRect content_rect; - NSRect frame_rect; inShowOrHide = YES; - - /* We move the window away when hiding, to make it possible to move it in - * place when showing to get reliable tracking rect events (which are used - * to generate crossing events). We have to do this, probably a bug in - * quartz. - */ - content_rect = NSMakeRect (-500 - impl->width, -500 - impl->height, - impl->width, impl->height); - frame_rect = [impl->toplevel frameRectForContentRect:content_rect]; - [impl->toplevel setFrame:frame_rect display:NO]; - [impl->toplevel orderOut:nil]; - inShowOrHide = NO; } @@ -461,8 +401,29 @@ drag_operation_to_drag_action (NSDragOperation operation) { GdkDragAction result = 0; + /* GDK and Quartz drag operations do not map 1:1. + * This mapping represents about the best that we + * can come up. + * + * Note that NSDragOperationPrivate and GDK_ACTION_PRIVATE + * have almost opposite meanings: the GDK one means that the + * destination is solely responsible for the action; the Quartz + * one means that the source and destination will agree + * privately on the action. NSOperationGeneric is close in meaning + * to GDK_ACTION_PRIVATE but there is a problem: it will be + * sent for any ordinary drag, and likely not understood + * by any intra-widget drag (since the source & dest are the + * same). + */ + if (operation & NSDragOperationGeneric) + result |= GDK_ACTION_MOVE; + if (operation & NSDragOperationCopy) result |= GDK_ACTION_COPY; + if (operation & NSDragOperationMove) + result |= GDK_ACTION_MOVE; + if (operation & NSDragOperationLink) + result |= GDK_ACTION_LINK; return result; } @@ -474,6 +435,10 @@ drag_action_to_drag_operation (GdkDragAction action) if (action & GDK_ACTION_COPY) result |= NSDragOperationCopy; + if (action & GDK_ACTION_LINK) + result |= NSDragOperationLink; + if (action & GDK_ACTION_MOVE) + result |= NSDragOperationMove; return result; } @@ -485,6 +450,7 @@ update_context_from_dragging_info (id sender) GDK_DRAG_CONTEXT_PRIVATE (current_context)->dragging_info = sender; current_context->suggested_action = drag_operation_to_drag_action ([sender draggingSourceOperationMask]); + current_context->actions = current_context->suggested_action; } - (NSDragOperation)draggingEntered:(id )sender @@ -510,6 +476,10 @@ update_context_from_dragging_info (id sender) - (void)draggingEnded:(id )sender { + /* leave a note for the source about what action was taken */ + if (_gdk_quartz_drag_source_context && current_context) + _gdk_quartz_drag_source_context->action = current_context->action; + if (current_context) g_object_unref (current_context); current_context = NULL; diff --git a/gdk/quartz/gdkcursor-quartz.c b/gdk/quartz/gdkcursor-quartz.c index 2431eb8aa4..651952f0c1 100644 --- a/gdk/quartz/gdkcursor-quartz.c +++ b/gdk/quartz/gdkcursor-quartz.c @@ -45,6 +45,21 @@ gdk_quartz_cursor_new_from_nscursor (NSCursor *nscursor, return cursor; } +static GdkCursor * +create_blank_cursor (void) +{ + NSCursor *nscursor; + NSImage *nsimage; + NSSize size = { 1.0, 1.0 }; + + nsimage = [[NSImage alloc] initWithSize:size]; + nscursor = [[NSCursor alloc] initWithImage:nsimage + hotSpot:NSMakePoint(0.0, 0.0)]; + [nsimage release]; + + return gdk_quartz_cursor_new_from_nscursor (nscursor, GDK_BLANK_CURSOR); +} + static gboolean get_bit (const guchar *data, gint width, @@ -79,7 +94,7 @@ create_builtin_cursor (GdkCursorType cursor_type) NSImage *image; NSCursor *nscursor; - if (cursor_type >= G_N_ELEMENTS (xcursors)) + if (cursor_type >= G_N_ELEMENTS (xcursors) || cursor_type < 0) return NULL; cursor = cached_xcursors[cursor_type]; @@ -210,6 +225,10 @@ gdk_cursor_new_for_display (GdkDisplay *display, case GDK_HAND2: nscursor = [NSCursor pointingHandCursor]; break; + case GDK_CURSOR_IS_PIXMAP: + return NULL; + case GDK_BLANK_CURSOR: + return create_blank_cursor (); default: return gdk_cursor_ref (create_builtin_cursor (cursor_type)); } diff --git a/gdk/quartz/gdkdisplay-quartz.c b/gdk/quartz/gdkdisplay-quartz.c index 9b83b13b72..9dbd93f18e 100644 --- a/gdk/quartz/gdkdisplay-quartz.c +++ b/gdk/quartz/gdkdisplay-quartz.c @@ -178,3 +178,9 @@ gdk_display_supports_composite (GdkDisplay *display) /* FIXME: Implement */ return FALSE; } + +gulong +_gdk_windowing_window_get_next_serial (GdkDisplay *display) +{ + return 0; +} diff --git a/gdk/quartz/gdkdnd-quartz.c b/gdk/quartz/gdkdnd-quartz.c index 40e90afe5b..948b4dd39a 100644 --- a/gdk/quartz/gdkdnd-quartz.c +++ b/gdk/quartz/gdkdnd-quartz.c @@ -101,6 +101,12 @@ gdk_drag_context_unref (GdkDragContext *context) GdkDragContext *_gdk_quartz_drag_source_context = NULL; +GdkDragContext * +gdk_quartz_drag_source_context () +{ + return _gdk_quartz_drag_source_context; +} + GdkDragContext * gdk_drag_begin (GdkWindow *window, GList *targets) diff --git a/gdk/quartz/gdkdrawable-quartz.c b/gdk/quartz/gdkdrawable-quartz.c index 9ad9c66d2e..b4b1e0364a 100644 --- a/gdk/quartz/gdkdrawable-quartz.c +++ b/gdk/quartz/gdkdrawable-quartz.c @@ -19,6 +19,7 @@ */ #include "config.h" +#include #include #include "gdkprivate-quartz.h" @@ -31,20 +32,56 @@ typedef struct { CGContextRef cg_context; } GdkQuartzCairoSurfaceData; +void +_gdk_windowing_set_cairo_surface_size (cairo_surface_t *surface, + int width, + int height) +{ + /* This is not supported with quartz surfaces. */ +} + static void gdk_quartz_cairo_surface_destroy (void *data) { GdkQuartzCairoSurfaceData *surface_data = data; GdkDrawableImplQuartz *impl = GDK_DRAWABLE_IMPL_QUARTZ (surface_data->drawable); - gdk_quartz_drawable_release_context (surface_data->drawable, - surface_data->cg_context); - impl->cairo_surface = NULL; + gdk_quartz_drawable_release_context (surface_data->drawable, + surface_data->cg_context); + g_free (surface_data); } +cairo_surface_t * +_gdk_windowing_create_cairo_surface (GdkDrawable *drawable, + int width, + int height) +{ + CGContextRef cg_context; + GdkQuartzCairoSurfaceData *surface_data; + cairo_surface_t *surface; + + cg_context = gdk_quartz_drawable_get_context (drawable, TRUE); + + if (!cg_context) + return NULL; + + surface_data = g_new (GdkQuartzCairoSurfaceData, 1); + surface_data->drawable = drawable; + surface_data->cg_context = cg_context; + + surface = cairo_quartz_surface_create_for_cg_context (cg_context, + width, height); + + cairo_surface_set_user_data (surface, &gdk_quartz_cairo_key, + surface_data, + gdk_quartz_cairo_surface_destroy); + + return surface; +} + static cairo_surface_t * gdk_quartz_ref_cairo_surface (GdkDrawable *drawable) { @@ -56,24 +93,11 @@ gdk_quartz_ref_cairo_surface (GdkDrawable *drawable) if (!impl->cairo_surface) { - CGContextRef cg_context; int width, height; - GdkQuartzCairoSurfaceData *surface_data; - - cg_context = gdk_quartz_drawable_get_context (drawable, TRUE); - if (!cg_context) - return NULL; gdk_drawable_get_size (drawable, &width, &height); - - impl->cairo_surface = cairo_quartz_surface_create_for_cg_context (cg_context, width, height); - - surface_data = g_new (GdkQuartzCairoSurfaceData, 1); - surface_data->drawable = drawable; - surface_data->cg_context = cg_context; - - cairo_surface_set_user_data (impl->cairo_surface, &gdk_quartz_cairo_key, - surface_data, gdk_quartz_cairo_surface_destroy); + impl->cairo_surface = _gdk_windowing_create_cairo_surface (drawable, + width, height); } else cairo_surface_reference (impl->cairo_surface); @@ -183,8 +207,6 @@ gdk_quartz_draw_arc (GdkDrawable *drawable, GDK_QUARTZ_CONTEXT_FILL : GDK_QUARTZ_CONTEXT_STROKE); - CGContextSaveGState (context); - start_angle = angle1 * 2.0 * G_PI / 360.0 / 64.0; end_angle = start_angle + angle2 * 2.0 * G_PI / 360.0 / 64.0; @@ -233,8 +255,6 @@ gdk_quartz_draw_arc (GdkDrawable *drawable, CGContextStrokePath (context); } - CGContextRestoreGState (context); - gdk_quartz_drawable_release_context (drawable, context); } @@ -311,55 +331,76 @@ gdk_quartz_draw_drawable (GdkDrawable *drawable, gint xdest, gint ydest, gint width, - gint height) + gint height, + GdkDrawable *original_src) { int src_depth = gdk_drawable_get_depth (src); int dest_depth = gdk_drawable_get_depth (drawable); GdkDrawableImplQuartz *src_impl; - if (GDK_IS_DRAWABLE_IMPL_QUARTZ (src)) + if (GDK_IS_WINDOW_IMPL_QUARTZ (src)) + { + GdkWindowImplQuartz *window_impl; + + window_impl = GDK_WINDOW_IMPL_QUARTZ (src); + + /* We do support moving areas on the same drawable, if it can be done + * by using a scroll. FIXME: We need to check that the params support + * this hack, and make sure it's done properly with any offsets etc? + */ + if (drawable == (GdkDrawable *)window_impl) + { + [window_impl->view scrollRect:NSMakeRect (xsrc, ysrc, width, height) + by:NSMakeSize (xdest - xsrc, ydest - ysrc)]; + + + } + else + g_warning ("Drawing with window source != dest is not supported"); + + return; + } + else if (GDK_IS_DRAWABLE_IMPL_QUARTZ (src)) src_impl = GDK_DRAWABLE_IMPL_QUARTZ (src); else if (GDK_IS_PIXMAP (src)) src_impl = GDK_DRAWABLE_IMPL_QUARTZ (GDK_PIXMAP_OBJECT (src)->impl); - else if (GDK_IS_WINDOW (src)) + else { - src_impl = GDK_DRAWABLE_IMPL_QUARTZ (GDK_WINDOW_OBJECT (src)->impl); - /* FIXME: Implement drawing a window. */ + g_warning ("Unsupported source %s", G_OBJECT_TYPE_NAME (src)); return; } - else - g_assert_not_reached (); - + + /* Handle drawable and pixmap sources. */ if (src_depth == 1) { /* FIXME: src depth 1 is not supported yet */ + g_warning ("Source with depth 1 unsupported"); } else if (dest_depth != 0 && src_depth == dest_depth) { + GdkPixmapImplQuartz *pixmap_impl = GDK_PIXMAP_IMPL_QUARTZ (src_impl); CGContextRef context = gdk_quartz_drawable_get_context (drawable, FALSE); if (!context) - return; + return; _gdk_quartz_gc_update_cg_context (gc, drawable, context, - GDK_QUARTZ_CONTEXT_STROKE); + GDK_QUARTZ_CONTEXT_STROKE); CGContextClipToRect (context, CGRectMake (xdest, ydest, width, height)); CGContextTranslateCTM (context, xdest - xsrc, ydest - ysrc + - GDK_PIXMAP_IMPL_QUARTZ (src_impl)->height); + pixmap_impl->height); CGContextScaleCTM (context, 1.0, -1.0); - CGContextDrawImage (context, - CGRectMake(0, 0, - GDK_PIXMAP_IMPL_QUARTZ (src_impl)->width, - GDK_PIXMAP_IMPL_QUARTZ (src_impl)->height), - GDK_PIXMAP_IMPL_QUARTZ (src_impl)->image); + CGContextDrawImage (context, + CGRectMake (0, 0, pixmap_impl->width, pixmap_impl->height), + pixmap_impl->image); gdk_quartz_drawable_release_context (drawable, context); } else g_warning ("Attempt to draw a drawable with depth %d to a drawable with depth %d", - src_depth, dest_depth); + src_depth, dest_depth); } static void @@ -620,7 +661,7 @@ gdk_drawable_impl_quartz_class_init (GdkDrawableImplQuartzClass *klass) drawable_class->draw_polygon = gdk_quartz_draw_polygon; drawable_class->draw_text = gdk_quartz_draw_text; drawable_class->draw_text_wc = gdk_quartz_draw_text_wc; - drawable_class->draw_drawable = gdk_quartz_draw_drawable; + drawable_class->draw_drawable_with_src = gdk_quartz_draw_drawable; drawable_class->draw_points = gdk_quartz_draw_points; drawable_class->draw_segments = gdk_quartz_draw_segments; drawable_class->draw_lines = gdk_quartz_draw_lines; @@ -681,6 +722,51 @@ gdk_quartz_drawable_get_context (GdkDrawable *drawable, return GDK_DRAWABLE_IMPL_QUARTZ_GET_CLASS (drawable)->get_context (drawable, antialias); } +/* Help preventing "beam sync penalty" where CG makes all graphics code + * block until the next vsync if we try to flush (including call display on + * a view) too often. We do this by limiting the manual flushing done + * outside of expose calls to less than some frequency when measured over + * the last 4 flushes. This is a bit arbitray, but seems to make it possible + * for some quick manual flushes (such as gtkruler or gimp's marching ants) + * without hitting the max flush frequency. + * + * If drawable NULL, no flushing is done, only registering that a flush was + * done externally. + */ +void +_gdk_quartz_drawable_flush (GdkDrawable *drawable) +{ + static struct timeval prev_tv; + static gint intervals[4]; + static gint index; + struct timeval tv; + gint ms; + + gettimeofday (&tv, NULL); + ms = (tv.tv_sec - prev_tv.tv_sec) * 1000 + (tv.tv_usec - prev_tv.tv_usec) / 1000; + intervals[index++ % 4] = ms; + + if (drawable) + { + ms = intervals[0] + intervals[1] + intervals[2] + intervals[3]; + + /* ~25Hz on average. */ + if (ms > 4*40) + { + if (GDK_IS_WINDOW_IMPL_QUARTZ (drawable)) + { + GdkWindowImplQuartz *window_impl = GDK_WINDOW_IMPL_QUARTZ (drawable); + + [window_impl->toplevel flushWindow]; + } + + prev_tv = tv; + } + } + else + prev_tv = tv; +} + void gdk_quartz_drawable_release_context (GdkDrawable *drawable, CGContextRef cg_context) @@ -694,7 +780,10 @@ gdk_quartz_drawable_release_context (GdkDrawable *drawable, /* See comment in gdk_quartz_drawable_get_context(). */ if (window_impl->in_paint_rect_count == 0) - [window_impl->view unlockFocus]; + { + _gdk_quartz_drawable_flush (drawable); + [window_impl->view unlockFocus]; + } } else if (GDK_IS_PIXMAP_IMPL_QUARTZ (drawable)) CGContextRelease (cg_context); diff --git a/gdk/quartz/gdkevents-quartz.c b/gdk/quartz/gdkevents-quartz.c index bc301955da..54baef7f52 100644 --- a/gdk/quartz/gdkevents-quartz.c +++ b/gdk/quartz/gdkevents-quartz.c @@ -33,78 +33,18 @@ #include "gdkkeysyms.h" #include "gdkprivate-quartz.h" -/* This is the window the mouse is currently over */ -static GdkWindow *current_mouse_window; +#define GRIP_WIDTH 15 +#define GRIP_HEIGHT 15 /* This is the window corresponding to the key window */ static GdkWindow *current_keyboard_window; -/* This is the pointer grab window */ -GdkWindow *_gdk_quartz_pointer_grab_window; -static gboolean pointer_grab_owner_events; -static GdkEventMask pointer_grab_event_mask; -static gboolean pointer_grab_implicit; - -/* This is the keyboard grab window */ -GdkWindow * _gdk_quartz_keyboard_grab_window; -static gboolean keyboard_grab_owner_events; - /* This is the event mask and button state from the last event */ static GdkEventMask current_event_mask; static int current_button_state; -static void get_child_coordinates_from_ancestor (GdkWindow *ancestor_window, - gint ancestor_x, - gint ancestor_y, - GdkWindow *child_window, - gint *child_x, - gint *child_y); -static void get_ancestor_coordinates_from_child (GdkWindow *child_window, - gint child_x, - gint child_y, - GdkWindow *ancestor_window, - gint *ancestor_x, - gint *ancestor_y); -static void get_converted_window_coordinates (GdkWindow *in_window, - gint in_x, - gint in_y, - GdkWindow *out_window, - gint *out_x, - gint *out_y); static void append_event (GdkEvent *event); -static const gchar * -which_window_is_this (GdkWindow *window) -{ - static gchar buf[256]; - const gchar *name = NULL; - gpointer widget; - - /* Get rid of compiler warning. */ - if (0) which_window_is_this (window); - - if (window == _gdk_root) - name = "root"; - else if (window == NULL) - name = "null"; - - if (window) - { - gdk_window_get_user_data (window, &widget); - if (widget) - name = G_OBJECT_TYPE_NAME (widget); - } - - if (!name) - name = "unknown"; - - snprintf (buf, 256, "<%s (%p)%s>", - name, window, - window == current_mouse_window ? ", is mouse" : ""); - - return buf; -} - NSEvent * gdk_quartz_event_get_nsevent (GdkEvent *event) { @@ -112,12 +52,11 @@ gdk_quartz_event_get_nsevent (GdkEvent *event) return ((GdkEventPrivate *) event)->windowing_data; } -void +void _gdk_events_init (void) { _gdk_quartz_event_loop_init (); - current_mouse_window = g_object_ref (_gdk_root); current_keyboard_window = g_object_ref (_gdk_root); } @@ -135,45 +74,26 @@ gdk_event_get_graphics_expose (GdkWindow *window) return NULL; } -static void -generate_grab_broken_event (GdkWindow *window, - gboolean keyboard, - gboolean implicit, - GdkWindow *grab_window) -{ - if (!GDK_WINDOW_DESTROYED (window)) - { - GdkEvent *event = gdk_event_new (GDK_GRAB_BROKEN); - - event->grab_broken.window = window; - event->grab_broken.send_event = 0; - event->grab_broken.keyboard = keyboard; - event->grab_broken.implicit = implicit; - event->grab_broken.grab_window = grab_window; - - append_event (event); - } -} - GdkGrabStatus gdk_keyboard_grab (GdkWindow *window, gint owner_events, guint32 time) { + GdkDisplay *display; + GdkWindow *toplevel; + g_return_val_if_fail (window != NULL, 0); g_return_val_if_fail (GDK_IS_WINDOW (window), 0); - if (_gdk_quartz_keyboard_grab_window) - { - if (_gdk_quartz_keyboard_grab_window != window) - generate_grab_broken_event (_gdk_quartz_keyboard_grab_window, - TRUE, FALSE, window); - - g_object_unref (_gdk_quartz_keyboard_grab_window); - } + display = gdk_drawable_get_display (window); + toplevel = gdk_window_get_toplevel (window); - _gdk_quartz_keyboard_grab_window = g_object_ref (window); - keyboard_grab_owner_events = owner_events; + _gdk_display_set_has_keyboard_grab (display, + window, + toplevel, + owner_events, + 0, + time); return GDK_GRAB_SUCCESS; } @@ -182,144 +102,62 @@ void gdk_display_keyboard_ungrab (GdkDisplay *display, guint32 time) { - if (_gdk_quartz_keyboard_grab_window) - g_object_unref (_gdk_quartz_keyboard_grab_window); - _gdk_quartz_keyboard_grab_window = NULL; -} - -gboolean -gdk_keyboard_grab_info_libgtk_only (GdkDisplay *display, - GdkWindow **grab_window, - gboolean *owner_events) -{ - if (_gdk_quartz_keyboard_grab_window) - { - if (grab_window) - *grab_window = _gdk_quartz_keyboard_grab_window; - if (owner_events) - *owner_events = keyboard_grab_owner_events; - - return TRUE; - } - - return FALSE; -} - -static void -pointer_ungrab_internal (gboolean only_if_implicit) -{ - if (!_gdk_quartz_pointer_grab_window) - return; - - if (only_if_implicit && !pointer_grab_implicit) - return; - - g_object_unref (_gdk_quartz_pointer_grab_window); - _gdk_quartz_pointer_grab_window = NULL; - - pointer_grab_owner_events = FALSE; - pointer_grab_event_mask = 0; - pointer_grab_implicit = FALSE; - - /* FIXME: Send crossing events */ -} - -gboolean -gdk_display_pointer_is_grabbed (GdkDisplay *display) -{ - return (_gdk_quartz_pointer_grab_window != NULL && - !pointer_grab_implicit); -} - -gboolean -gdk_pointer_grab_info_libgtk_only (GdkDisplay *display, - GdkWindow **grab_window, - gboolean *owner_events) -{ - if (!_gdk_quartz_pointer_grab_window) - return FALSE; - - if (grab_window) - *grab_window = _gdk_quartz_pointer_grab_window; - - if (owner_events) - *owner_events = pointer_grab_owner_events; - - return TRUE; + _gdk_display_unset_has_keyboard_grab (display, FALSE); } void gdk_display_pointer_ungrab (GdkDisplay *display, guint32 time) { - pointer_ungrab_internal (FALSE); -} + GdkPointerGrabInfo *grab; -static GdkGrabStatus -pointer_grab_internal (GdkWindow *window, - gboolean owner_events, - GdkEventMask event_mask, - GdkWindow *confine_to, - GdkCursor *cursor, - gboolean implicit) -{ - /* FIXME: Send crossing events */ - - _gdk_quartz_pointer_grab_window = g_object_ref (window); - pointer_grab_owner_events = owner_events; - pointer_grab_event_mask = event_mask; - pointer_grab_implicit = implicit; + grab = _gdk_display_get_last_pointer_grab (display); + if (grab) + grab->serial_end = 0; - return GDK_GRAB_SUCCESS; + _gdk_display_pointer_grab_update (display, 0); } GdkGrabStatus -gdk_pointer_grab (GdkWindow *window, - gboolean owner_events, - GdkEventMask event_mask, - GdkWindow *confine_to, - GdkCursor *cursor, - guint32 time) +_gdk_windowing_pointer_grab (GdkWindow *window, + GdkWindow *native, + gboolean owner_events, + GdkEventMask event_mask, + GdkWindow *confine_to, + GdkCursor *cursor, + guint32 time) { g_return_val_if_fail (GDK_IS_WINDOW (window), 0); g_return_val_if_fail (confine_to == NULL || GDK_IS_WINDOW (confine_to), 0); - if (_gdk_quartz_pointer_grab_window) - { - if (_gdk_quartz_pointer_grab_window != window) - generate_grab_broken_event (_gdk_quartz_pointer_grab_window, - FALSE, pointer_grab_implicit, window); + _gdk_display_add_pointer_grab (_gdk_display, + window, + native, + owner_events, + event_mask, + 0, + time, + FALSE); - pointer_ungrab_internal (FALSE); - } - - return pointer_grab_internal (window, owner_events, event_mask, - confine_to, cursor, FALSE); + return GDK_GRAB_SUCCESS; } -/* This is used to break any grabs in the case where we have to due to - * the grab emulation. Instead of enforcing the desktop wide grab, we - * break it when the app loses focus for example. - */ static void -break_all_grabs (void) +break_all_grabs (guint32 time) { - if (_gdk_quartz_keyboard_grab_window) + GdkPointerGrabInfo *grab; + + if (_gdk_display->keyboard_grab.window) + _gdk_display_unset_has_keyboard_grab (_gdk_display, FALSE); + + grab = _gdk_display_get_last_pointer_grab (_gdk_display); + if (grab) { - generate_grab_broken_event (_gdk_quartz_keyboard_grab_window, - TRUE, FALSE, - NULL); - g_object_unref (_gdk_quartz_keyboard_grab_window); - _gdk_quartz_keyboard_grab_window = NULL; + grab->serial_end = 0; + grab->implicit_ungrab = TRUE; } - if (_gdk_quartz_pointer_grab_window) - { - generate_grab_broken_event (_gdk_quartz_pointer_grab_window, - FALSE, pointer_grab_implicit, - NULL); - pointer_ungrab_internal (FALSE); - } + _gdk_display_pointer_grab_update (_gdk_display, 0); } static void @@ -341,81 +179,27 @@ append_event (GdkEvent *event) _gdk_event_queue_append (_gdk_display, event); } -static GdkFilterReturn -apply_filters (GdkWindow *window, - NSEvent *nsevent, - GList *filters) +static gint +gdk_event_apply_filters (NSEvent *nsevent, + GdkEvent *event, + GList *filters) { - GdkFilterReturn result = GDK_FILTER_CONTINUE; - GdkEvent *event; - GList *node; GList *tmp_list; - - event = gdk_event_new (GDK_NOTHING); - if (window != NULL) - event->any.window = g_object_ref (window); - ((GdkEventPrivate *)event)->flags |= GDK_EVENT_PENDING; - - /* I think GdkFilterFunc semantics require the passed-in event - * to already be in the queue. The filter func can generate - * more events and append them after it if it likes. - */ - node = _gdk_event_queue_append (_gdk_display, event); + GdkFilterReturn result; tmp_list = filters; + while (tmp_list) { - GdkEventFilter *filter = (GdkEventFilter *) tmp_list->data; + GdkEventFilter *filter = (GdkEventFilter*) tmp_list->data; tmp_list = tmp_list->next; result = filter->function (nsevent, event, filter->data); - if (result != GDK_FILTER_CONTINUE) - break; + if (result != GDK_FILTER_CONTINUE) + return result; } - if (result == GDK_FILTER_CONTINUE || result == GDK_FILTER_REMOVE) - { - _gdk_event_queue_remove_link (_gdk_display, node); - g_list_free_1 (node); - gdk_event_free (event); - } - else /* GDK_FILTER_TRANSLATE */ - { - ((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING; - fixup_event (event); - } - return result; -} - -/* Checks if the passed in window is interested in the event mask, and - * if so, it's returned. If not, the event can be propagated through - * its ancestors until one with the right event mask is found, up to - * the nearest toplevel. - */ -static GdkWindow * -find_window_interested_in_event_mask (GdkWindow *window, - GdkEventMask event_mask, - gboolean propagate) -{ - GdkWindowObject *private; - - private = GDK_WINDOW_OBJECT (window); - while (private) - { - if (private->event_mask & event_mask) - return (GdkWindow *)private; - - if (!propagate) - return NULL; - - /* Don't traverse beyond toplevels. */ - if (GDK_WINDOW_TYPE (private) != GDK_WINDOW_CHILD) - break; - - private = private->parent; - } - - return NULL; + return GDK_FILTER_CONTINUE; } static guint32 @@ -540,6 +324,14 @@ get_event_mask_from_ns_event (NSEvent *nsevent) g_assert_not_reached (); } } + break; + + case NSMouseEntered: + return GDK_ENTER_NOTIFY_MASK; + + case NSMouseExited: + return GDK_LEAVE_NOTIFY_MASK; + default: g_assert_not_reached (); } @@ -598,695 +390,51 @@ _gdk_quartz_events_update_focus_window (GdkWindow *window, } } -static void -convert_window_coordinates_to_root (GdkWindow *window, - gdouble x, - gdouble y, - gdouble *x_root, - gdouble *y_root) +void +_gdk_quartz_events_send_map_event (GdkWindow *window) { - gint ox, oy; - - *x_root = x; - *y_root = y; - - if (gdk_window_get_origin (window, &ox, &oy)) - { - *x_root += ox; - *y_root += oy; - } -} - -/* FIXME: Refactor and share with scroll event. */ -static GdkEvent * -create_crossing_event (GdkWindow *window, - NSEvent *nsevent, - GdkEventType event_type, - GdkCrossingMode mode, - GdkNotifyType detail) -{ - GdkEvent *event; - gint x_tmp, y_tmp; - - event = gdk_event_new (event_type); - - event->crossing.window = window; - event->crossing.subwindow = NULL; /* FIXME */ - event->crossing.time = get_time_from_ns_event (nsevent); - - /* Split out this block: */ - { - NSWindow *nswindow; - GdkWindow *toplevel; - GdkWindowImplQuartz *impl; - NSPoint point; - - nswindow = [nsevent window]; - point = [nsevent locationInWindow]; - - toplevel = [(GdkQuartzView *)[nswindow contentView] gdkWindow]; - - impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (toplevel)->impl); - - x_tmp = point.x; - y_tmp = impl->height - point.y; - - get_converted_window_coordinates (toplevel, - x_tmp, y_tmp, - window, - &x_tmp, &y_tmp); - } - - event->crossing.x = x_tmp; - event->crossing.y = y_tmp; - - convert_window_coordinates_to_root (window, - event->crossing.x, - event->crossing.y, - &event->crossing.x_root, - &event->crossing.y_root); - - event->crossing.mode = mode; - event->crossing.detail = detail; - event->crossing.state = get_keyboard_modifiers_from_ns_event (nsevent); - - /* FIXME: focus and button state */ - - return event; -} - -static void -synthesize_enter_event (GdkWindow *window, - NSEvent *nsevent, - GdkCrossingMode mode, - GdkNotifyType detail) -{ - GdkEvent *event; - - if (_gdk_quartz_pointer_grab_window != NULL && - !pointer_grab_owner_events && - !(pointer_grab_event_mask & GDK_ENTER_NOTIFY_MASK)) - return; - - if (!(GDK_WINDOW_OBJECT (window)->event_mask & GDK_ENTER_NOTIFY_MASK)) - return; - - event = create_crossing_event (window, nsevent, GDK_ENTER_NOTIFY, - mode, detail); - - append_event (event); -} - -static void -synthesize_enter_events (GdkWindow *from, - GdkWindow *to, - NSEvent *nsevent, - GdkCrossingMode mode, - GdkNotifyType detail) -{ - GdkWindow *prev = gdk_window_get_parent (to); - - if (prev != from) - synthesize_enter_events (from, prev, nsevent, mode, detail); - synthesize_enter_event (to, nsevent, mode, detail); -} - -static void -synthesize_leave_event (GdkWindow *window, - NSEvent *nsevent, - GdkCrossingMode mode, - GdkNotifyType detail) -{ - GdkEvent *event; - - if (_gdk_quartz_pointer_grab_window != NULL && - !pointer_grab_owner_events && - !(pointer_grab_event_mask & GDK_LEAVE_NOTIFY_MASK)) - return; - - if (!(GDK_WINDOW_OBJECT (window)->event_mask & GDK_LEAVE_NOTIFY_MASK)) - return; - - event = create_crossing_event (window, nsevent, GDK_LEAVE_NOTIFY, - mode, detail); - - append_event (event); -} - -static void -synthesize_leave_events (GdkWindow *from, - GdkWindow *to, - NSEvent *nsevent, - GdkCrossingMode mode, - GdkNotifyType detail) -{ - GdkWindow *next = gdk_window_get_parent (from); - - synthesize_leave_event (from, nsevent, mode, detail); - if (next != to) - synthesize_leave_events (next, to, nsevent, mode, detail); -} - -static void -synthesize_crossing_events (GdkWindow *window, - GdkCrossingMode mode, - NSEvent *nsevent, - gint x, - gint y) -{ - GdkWindow *intermediate, *tem, *common_ancestor; - - if (window == current_mouse_window) - return; - - if (_gdk_quartz_window_is_ancestor (current_mouse_window, window)) - { - /* Pointer has moved to an inferior window. */ - synthesize_leave_event (current_mouse_window, nsevent, mode, GDK_NOTIFY_INFERIOR); - - /* If there are intermediate windows, generate ENTER_NOTIFY - * events for them - */ - intermediate = gdk_window_get_parent (window); - - if (intermediate != current_mouse_window) - { - synthesize_enter_events (current_mouse_window, intermediate, nsevent, mode, GDK_NOTIFY_VIRTUAL); - } - - synthesize_enter_event (window, nsevent, mode, GDK_NOTIFY_ANCESTOR); - } - else if (_gdk_quartz_window_is_ancestor (window, current_mouse_window)) - { - /* Pointer has moved to an ancestor window. */ - synthesize_leave_event (current_mouse_window, nsevent, mode, GDK_NOTIFY_ANCESTOR); - - /* If there are intermediate windows, generate LEAVE_NOTIFY - * events for them - */ - intermediate = gdk_window_get_parent (current_mouse_window); - if (intermediate != window) - { - synthesize_leave_events (intermediate, window, nsevent, mode, GDK_NOTIFY_VIRTUAL); - } - - synthesize_enter_event (window, nsevent, mode, GDK_NOTIFY_INFERIOR); - } - else if (current_mouse_window) - { - /* Find least common ancestor of current_mouse_window and window */ - tem = current_mouse_window; - do { - common_ancestor = gdk_window_get_parent (tem); - tem = common_ancestor; - } while (common_ancestor && - !_gdk_quartz_window_is_ancestor (common_ancestor, window)); - if (common_ancestor) - { - synthesize_leave_event (current_mouse_window, nsevent, mode, GDK_NOTIFY_NONLINEAR); - intermediate = gdk_window_get_parent (current_mouse_window); - if (intermediate != common_ancestor) - { - synthesize_leave_events (intermediate, common_ancestor, - nsevent, mode, GDK_NOTIFY_NONLINEAR_VIRTUAL); - } - intermediate = gdk_window_get_parent (window); - if (intermediate != common_ancestor) - { - synthesize_enter_events (common_ancestor, intermediate, - nsevent, mode, GDK_NOTIFY_NONLINEAR_VIRTUAL); - } - synthesize_enter_event (window, nsevent, mode, GDK_NOTIFY_NONLINEAR); - } - } - else - { - /* This means we have no current_mouse_window, which probably - * means that there is a bug somewhere, we should always have - * the root in we don't have another window. Does this ever - * happen? - */ - g_warning ("Trying to create crossing event when current_mouse_window is NULL"); - } - - _gdk_quartz_events_update_mouse_window (window); - - /* FIXME: This does't work when someone calls gdk_window_set_cursor - * during a grab. The right behavior is that the cursor doesn't - * change when a grab is in effect, but in that case it does. - */ - if (window && !_gdk_quartz_pointer_grab_window) - _gdk_quartz_events_update_cursor (window); -} - -void -_gdk_quartz_events_send_map_events (GdkWindow *window) -{ - GList *list; - GdkWindow *interested_window; GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl); - interested_window = find_window_interested_in_event_mask (window, - GDK_STRUCTURE_MASK, - TRUE); - - if (interested_window) - { - GdkEvent *event = gdk_event_new (GDK_MAP); - event->any.window = interested_window; - append_event (event); - } - - for (list = private->children; list != NULL; list = list->next) - _gdk_quartz_events_send_map_events ((GdkWindow *)list->data); -} - -/* Get current mouse window */ -GdkWindow * -_gdk_quartz_events_get_mouse_window (gboolean consider_grabs) -{ - if (!consider_grabs) - return current_mouse_window; - - if (_gdk_quartz_pointer_grab_window && !pointer_grab_owner_events) - return _gdk_quartz_pointer_grab_window; - - return current_mouse_window; -} - -/* Update mouse window */ -void -_gdk_quartz_events_update_mouse_window (GdkWindow *window) -{ - if (window == current_mouse_window) + if (!impl->toplevel) return; -#ifdef G_ENABLE_DEBUG - if (_gdk_debug_flags & GDK_DEBUG_EVENTS) - _gdk_quartz_window_debug_highlight (window, 0); -#endif /* G_ENABLE_DEBUG */ - - if (window) - g_object_ref (window); - if (current_mouse_window) - g_object_unref (current_mouse_window); - - current_mouse_window = window; -} - -/* Update current cursor */ -void -_gdk_quartz_events_update_cursor (GdkWindow *window) -{ - GdkWindowObject *private = GDK_WINDOW_OBJECT (window); - NSCursor *nscursor = nil; - - while (private) + if (private->event_mask & GDK_STRUCTURE_MASK) { - GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl); + GdkEvent event; - nscursor = impl->nscursor; - if (nscursor) - break; - - private = private->parent; + event.any.type = GDK_MAP; + event.any.window = window; + + gdk_event_put (&event); } - - GDK_QUARTZ_ALLOC_POOL; - - if (!nscursor) - nscursor = [NSCursor arrowCursor]; - - if ([NSCursor currentCursor] != nscursor) - [nscursor set]; - - GDK_QUARTZ_RELEASE_POOL; } -/* Translates coordinates from an ancestor window + coords, to - * coordinates that are relative the child window. - */ -static void -get_child_coordinates_from_ancestor (GdkWindow *ancestor_window, - gint ancestor_x, - gint ancestor_y, - GdkWindow *child_window, - gint *child_x, - gint *child_y) -{ - GdkWindowObject *ancestor_private = GDK_WINDOW_OBJECT (ancestor_window); - GdkWindowObject *child_private = GDK_WINDOW_OBJECT (child_window); - - while (child_private != ancestor_private) - { - ancestor_x -= child_private->x; - ancestor_y -= child_private->y; - - child_private = child_private->parent; - } - - *child_x = ancestor_x; - *child_y = ancestor_y; -} - -/* Translates coordinates from a child window + coords, to - * coordinates that are relative the ancestor window. - */ -static void -get_ancestor_coordinates_from_child (GdkWindow *child_window, - gint child_x, - gint child_y, - GdkWindow *ancestor_window, - gint *ancestor_x, - gint *ancestor_y) -{ - GdkWindowObject *child_private = GDK_WINDOW_OBJECT (child_window); - GdkWindowObject *ancestor_private = GDK_WINDOW_OBJECT (ancestor_window); - - while (child_private != ancestor_private) - { - child_x += child_private->x; - child_y += child_private->y; - - child_private = child_private->parent; - } - - *ancestor_x = child_x; - *ancestor_y = child_y; -} - -/* Translates coordinates relative to one window (in_window) into - * coordinates relative to another window (out_window). - */ -static void -get_converted_window_coordinates (GdkWindow *in_window, - gint in_x, - gint in_y, - GdkWindow *out_window, - gint *out_x, - gint *out_y) -{ - GdkWindow *in_toplevel; - GdkWindow *out_toplevel; - int in_origin_x, in_origin_y; - int out_origin_x, out_origin_y; - - if (in_window == out_window) - { - *out_x = in_x; - *out_y = in_y; - return; - } - - /* First translate to "in" toplevel coordinates, then on to "out" - * toplevel coordinates, and finally to "out" child (the passed in - * window) coordinates. - */ - - in_toplevel = gdk_window_get_toplevel (in_window); - out_toplevel = gdk_window_get_toplevel (out_window); - - /* Translate in_x, in_y to "in" toplevel coordinates. */ - get_ancestor_coordinates_from_child (in_window, in_x, in_y, - in_toplevel, &in_x, &in_y); - - gdk_window_get_origin (in_toplevel, &in_origin_x, &in_origin_y); - gdk_window_get_origin (out_toplevel, &out_origin_x, &out_origin_y); - - /* Translate in_x, in_y to "out" toplevel coordinates. */ - in_x -= out_origin_x - in_origin_x; - in_y -= out_origin_y - in_origin_y; - - get_child_coordinates_from_ancestor (out_toplevel, - in_x, in_y, - out_window, - out_x, out_y); -} - -/* Given a mouse NSEvent (must be a mouse event for a GDK window), - * finds the subwindow over which the pointer is located. Returns - * coordinates relative to the found window. If no window is found, - * returns the root window, and root window coordinates. - */ static GdkWindow * -find_mouse_window_for_ns_event (NSEvent *nsevent, - gint *x_ret, - gint *y_ret) +find_toplevel_under_pointer (GdkDisplay *display, + NSPoint screen_point, + gint *x, + gint *y) { - GdkWindow *event_toplevel; - GdkWindowImplQuartz *impl; - GdkWindow *mouse_toplevel; - GdkWindow *mouse_window; - NSPoint point; - gint x_tmp, y_tmp; - - event_toplevel = [(GdkQuartzView *)[[nsevent window] contentView] gdkWindow]; - impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (event_toplevel)->impl); - point = [nsevent locationInWindow]; - - x_tmp = point.x; - y_tmp = impl->height - point.y; - - mouse_toplevel = gdk_window_get_toplevel (current_mouse_window); - - get_converted_window_coordinates (event_toplevel, - x_tmp, y_tmp, - mouse_toplevel, - &x_tmp, &y_tmp); - - mouse_window = _gdk_quartz_window_find_child (mouse_toplevel, x_tmp, y_tmp); - if (mouse_window && mouse_window != mouse_toplevel) - { - get_child_coordinates_from_ancestor (mouse_toplevel, - x_tmp, y_tmp, - mouse_window, - &x_tmp, &y_tmp); - } - else if (!mouse_window) - { - /* This happens for events on the window title buttons and the - * desktop, treat those as being on the root window. - */ - get_converted_window_coordinates (mouse_toplevel, - x_tmp, y_tmp, - _gdk_root, - &x_tmp, &y_tmp); - mouse_window = _gdk_root; - } - - *x_ret = x_tmp; - *y_ret = y_tmp; - - return mouse_window; -} - -/* Trigger crossing events if necessary. This is used when showing a new - * window, since the tracking rect API doesn't work reliably when a window - * shows up under the mouse cursor. It's done by finding the topmost window - * under the mouse pointer and synthesizing crossing events into that - * window. - */ -void -_gdk_quartz_events_trigger_crossing_events (gboolean defer_to_mainloop) -{ - NSPoint point; - gint x, y; - gint x_toplevel, y_toplevel; - GdkWindow *mouse_window; GdkWindow *toplevel; - GdkWindowImplQuartz *impl; - guint flags = 0; - NSTimeInterval timestamp = 0; - NSEvent *current_event; - NSEvent *nsevent; - if (defer_to_mainloop) + toplevel = display->pointer_info.toplevel_under_pointer; + if (toplevel) { - nsevent = [NSEvent otherEventWithType:NSApplicationDefined - location:NSZeroPoint - modifierFlags:0 - timestamp:0 - windowNumber:0 - context:nil - subtype:GDK_QUARTZ_EVENT_SUBTYPE_FAKE_CROSSING - data1:0 - data2:0]; - [NSApp postEvent:nsevent atStart:NO]; - return; + GdkWindowObject *private; + NSWindow *nswindow; + NSPoint point; + + private = (GdkWindowObject *)toplevel; + nswindow = ((GdkWindowImplQuartz *)private->impl)->toplevel; + + point = [nswindow convertScreenToBase:screen_point]; + + *x = point.x; + *y = private->height - point.y; } - point = [NSEvent mouseLocation]; - x = point.x; - y = _gdk_quartz_window_get_inverted_screen_y (point.y); - - mouse_window = _gdk_quartz_window_find_child (_gdk_root, x, y); - if (!mouse_window || mouse_window == _gdk_root) - return; - - toplevel = gdk_window_get_toplevel (mouse_window); - - /* We ignore crossing within the same toplevel since that is already - * handled elsewhere. - */ - if (toplevel == gdk_window_get_toplevel (current_mouse_window)) - return; - - get_converted_window_coordinates (_gdk_root, - x, y, - toplevel, - &x_toplevel, &y_toplevel); - - get_converted_window_coordinates (_gdk_root, - x, y, - mouse_window, - &x, &y); - - /* Fix up the event to be less fake if possible. */ - current_event = [NSApp currentEvent]; - if (current_event) - { - flags = [current_event modifierFlags]; - timestamp = [current_event timestamp]; - } - - if (timestamp == 0) - timestamp = GetCurrentEventTime (); - - impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (toplevel)->impl); - nsevent = [NSEvent otherEventWithType:NSApplicationDefined - location:NSMakePoint (x_toplevel, impl->height - y_toplevel) - modifierFlags:flags - timestamp:timestamp - windowNumber:[impl->toplevel windowNumber] - context:nil - subtype:GDK_QUARTZ_EVENT_SUBTYPE_FAKE_CROSSING - data1:0 - data2:0]; - -#ifdef G_ENABLE_DEBUG - /*_gdk_quartz_window_debug_highlight (mouse_window, 0);*/ -#endif - - synthesize_crossing_events (mouse_window, GDK_CROSSING_NORMAL, nsevent, x, y); -} - -/* Synthesizes crossing events if necessary, based on the passed in - * NSEvent. Uses NSMouseEntered and NSMouseExisted for toplevels and - * the mouse moved/dragged events for child windows, to see if the - * mouse window has changed. - */ -static void -synthesize_crossing_events_for_ns_event (NSEvent *nsevent) -{ - NSEventType event_type; - GdkWindow *mouse_window; - gint x; - gint y; - - event_type = [nsevent type]; - - switch (event_type) - { - case NSMouseMoved: - case NSLeftMouseDragged: - case NSRightMouseDragged: - case NSOtherMouseDragged: - /* We only handle moving the pointer to another GDK window. - * Leaving to a non-GDK toplevel window (or window title bar or - * the desktop) is covered by NSMouseExited events. - */ - mouse_window = find_mouse_window_for_ns_event (nsevent, &x, &y); - if (mouse_window != _gdk_root) - synthesize_crossing_events (mouse_window, GDK_CROSSING_NORMAL, nsevent, x, y); - - break; - - case NSMouseEntered: - { - GdkWindow *event_toplevel; - GdkWindowImplQuartz *impl; - NSPoint point; - - /* This is the only case where we actually use the window from - * the event since we need to know which toplevel we entered - * so it can be tracked properly. - */ - event_toplevel = [(GdkQuartzView *)[[nsevent window] contentView] gdkWindow]; - impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (event_toplevel)->impl); - - point = [nsevent locationInWindow]; - - x = point.x; - y = impl->height - point.y; - - mouse_window = _gdk_quartz_window_find_child (event_toplevel, x, y); - - /* Treat unknown windows (like the title bar buttons or - * desktop) as the root window. - */ - if (!mouse_window) - mouse_window = _gdk_root; - - if (mouse_window != event_toplevel) - get_converted_window_coordinates (event_toplevel, - x, y, - mouse_window, - &x, &y); - - synthesize_crossing_events (mouse_window, GDK_CROSSING_NORMAL, nsevent, x, y); - } - break; - - case NSMouseExited: - { - GdkWindow *event_toplevel; - GdkWindowImplQuartz *impl; - NSPoint point; - - /* We only use NSMouseExited when leaving to the root - * window. The other cases are handled above by checking the - * motion/button events, or getting a NSMouseEntered for - * another GDK window. The reason we don't use NSMouseExited - * for other windows is that quartz first delivers the entered - * event and then the exited which is the opposite from what - * we need. - */ - event_toplevel = [(GdkQuartzView *)[[nsevent window] contentView] gdkWindow]; - impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (event_toplevel)->impl); - point = [nsevent locationInWindow]; - - x = point.x; - y = impl->height - point.y; - - x += GDK_WINDOW_OBJECT (event_toplevel)->x; - y += GDK_WINDOW_OBJECT (event_toplevel)->y; - - /* If there is a window other than the root window at this - * position, it means we didn't exit to the root window and we - * ignore the event. (Note that we can get NULL here when swithing - * spaces for example.) - * - * FIXME: This is not enough, it doesn't catch the case where - * we leave a GDK window to a non-GDK window that has GDK - * windows below it. - */ - mouse_window = _gdk_quartz_window_find_child (_gdk_root, x, y); - - if (!mouse_window || - gdk_window_get_toplevel (mouse_window) == - gdk_window_get_toplevel (current_mouse_window)) - { - mouse_window = _gdk_root; - } - - if (mouse_window == _gdk_root) - synthesize_crossing_events (_gdk_root, GDK_CROSSING_NORMAL, nsevent, x, y); - } - break; - - default: - break; - } + return toplevel; } /* This function finds the correct window to send an event to, taking @@ -1295,10 +443,31 @@ synthesize_crossing_events_for_ns_event (NSEvent *nsevent) static GdkWindow * find_window_for_ns_event (NSEvent *nsevent, gint *x, - gint *y) + gint *y, + gint *x_root, + gint *y_root) { + GdkQuartzView *view; + GdkWindow *toplevel; + GdkWindowObject *private; + NSPoint point; + NSPoint screen_point; NSEventType event_type; + view = (GdkQuartzView *)[[nsevent window] contentView]; + + toplevel = [view gdkWindow]; + private = GDK_WINDOW_OBJECT (toplevel); + + point = [nsevent locationInWindow]; + screen_point = [[nsevent window] convertBaseToScreen:point]; + + *x = point.x; + *y = private->height - point.y; + + *x_root = screen_point.x; + *y_root = _gdk_quartz_window_get_inverted_screen_y (screen_point.y); + event_type = [nsevent type]; switch (event_type) @@ -1315,9 +484,10 @@ find_window_for_ns_event (NSEvent *nsevent, case NSRightMouseDragged: case NSOtherMouseDragged: { - GdkWindow *mouse_window; - GdkEventMask event_mask; - GdkWindow *real_window; + GdkDisplay *display; + GdkPointerGrabInfo *grab; + + display = gdk_drawable_get_display (toplevel); /* From the docs for XGrabPointer: * @@ -1327,53 +497,57 @@ find_window_for_ns_event (NSEvent *nsevent, * the grab_window and is reported only if selected by * event_mask. For either value of owner_events, unreported * events are discarded. - * - * This means we first try the owner, then the grab window, - * then give up. */ - if (_gdk_quartz_pointer_grab_window) + grab = _gdk_display_get_last_pointer_grab (display); + if (grab) { - if (pointer_grab_owner_events) - { - mouse_window = find_mouse_window_for_ns_event (nsevent, x, y); - event_mask = get_event_mask_from_ns_event (nsevent); - real_window = find_window_interested_in_event_mask (mouse_window, event_mask, TRUE); - - if (mouse_window && real_window && mouse_window != real_window) - get_ancestor_coordinates_from_child (mouse_window, - *x, *y, - real_window, - x, y); + /* Implicit grabs do not go through XGrabPointer and thus the + * event mask should not be checked. + */ + if (!grab->implicit + && (grab->event_mask & get_event_mask_from_ns_event (nsevent)) == 0) + return NULL; - if (real_window) - return real_window; - } - - /* Finally check the grab window. */ - if (pointer_grab_event_mask & get_event_mask_from_ns_event (nsevent)) - { - GdkWindow *event_toplevel; - GdkWindow *grab_toplevel; - NSPoint point; - int x_tmp, y_tmp; - - event_toplevel = [(GdkQuartzView *)[[nsevent window] contentView] gdkWindow]; - grab_toplevel = gdk_window_get_toplevel (_gdk_quartz_pointer_grab_window); - point = [nsevent locationInWindow]; - - x_tmp = point.x; - y_tmp = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (grab_toplevel)->impl)->height - point.y; - - /* Translate the coordinates so they are relative to - * the grab window instead of the event toplevel for - * the cases where they are not the same. + if (grab->owner_events) + { + /* For owner events, we need to use the toplevel under the + * pointer, not the window from the NSEvent, since that is + * reported with respect to the key window, which could be + * wrong. */ - get_converted_window_coordinates (event_toplevel, - x_tmp, y_tmp, - _gdk_quartz_pointer_grab_window, - x, y); + GdkWindow *toplevel_under_pointer; + gint x_tmp, y_tmp; - return _gdk_quartz_pointer_grab_window; + toplevel_under_pointer = find_toplevel_under_pointer (display, + screen_point, + &x_tmp, &y_tmp); + if (toplevel_under_pointer) + { + toplevel = toplevel_under_pointer; + *x = x_tmp; + *y = y_tmp; + } + + return toplevel; + } + else + { + /* Finally check the grab window. */ + GdkWindow *grab_toplevel; + GdkWindowObject *grab_private; + NSWindow *grab_nswindow; + + grab_toplevel = gdk_window_get_toplevel (grab->window); + grab_private = (GdkWindowObject *)grab_toplevel; + + grab_nswindow = ((GdkWindowImplQuartz *)grab_private->impl)->toplevel; + point = [grab_nswindow convertScreenToBase:screen_point]; + + /* Note: x_root and y_root are already right. */ + *x = point.x; + *y = grab_private->height - point.y; + + return grab_toplevel; } return NULL; @@ -1381,42 +555,84 @@ find_window_for_ns_event (NSEvent *nsevent, else { /* The non-grabbed case. */ - mouse_window = find_mouse_window_for_ns_event (nsevent, x, y); - event_mask = get_event_mask_from_ns_event (nsevent); - real_window = find_window_interested_in_event_mask (mouse_window, event_mask, TRUE); - - /* We have to translate the coordinates if the actual - * window is different from the mouse window. - */ - if (mouse_window && real_window && mouse_window != real_window) - get_ancestor_coordinates_from_child (mouse_window, - *x, *y, - real_window, - x, y); + GdkWindow *toplevel_under_pointer; + gint x_tmp, y_tmp; - return real_window; + /* Ignore all events but mouse moved that might be on the title + * bar (above the content view). The reason is that otherwise + * gdk gets confused about getting e.g. button presses with no + * window (the title bar is not known to it). + */ + if (event_type != NSMouseMoved) + if (*y < 0) + return NULL; + + /* As for owner events, we need to use the toplevel under the + * pointer, not the window from the NSEvent. + */ + toplevel_under_pointer = find_toplevel_under_pointer (display, + screen_point, + &x_tmp, &y_tmp); + if (toplevel_under_pointer) + { + GdkWindowObject *toplevel_private; + GdkWindowImplQuartz *toplevel_impl; + + toplevel = toplevel_under_pointer; + + toplevel_private = (GdkWindowObject *)toplevel; + toplevel_impl = (GdkWindowImplQuartz *)toplevel_private->impl; + + if ([toplevel_impl->toplevel showsResizeIndicator]) + { + NSRect frame; + + /* If the resize indicator is visible and the event + * is in the lower right 15x15 corner, we leave these + * events to Cocoa as to be handled as resize events. + * Applications may have widgets in this area. These + * will most likely be larger than 15x15 and for + * scroll bars there are also other means to move + * the scroll bar. Since the resize indicator is + * the only way of resizing windows on Mac OS, it + * is too important to not make functional. + */ + frame = [toplevel_impl->view bounds]; + if (x_tmp > frame.size.width - GRIP_WIDTH + && x_tmp < frame.size.width + && y_tmp > frame.size.height - GRIP_HEIGHT + && y_tmp < frame.size.height) + { + return NULL; + } + } + + *x = x_tmp; + *y = y_tmp; + } + + return toplevel; } } break; case NSMouseEntered: case NSMouseExited: - /* Already handled in synthesize_crossing_events_for_ns_event. */ - break; + /* Only handle our own entered/exited events, not the ones for the + * titlebar buttons. + */ + if ([view trackingRect] == [nsevent trackingNumber]) + return toplevel; + else + return NULL; case NSKeyDown: case NSKeyUp: case NSFlagsChanged: - { - GdkEventMask event_mask; + if (_gdk_display->keyboard_grab.window && !_gdk_display->keyboard_grab.owner_events) + return gdk_window_get_toplevel (_gdk_display->keyboard_grab.window); - if (_gdk_quartz_keyboard_grab_window && !keyboard_grab_owner_events) - return _gdk_quartz_keyboard_grab_window; - - event_mask = get_event_mask_from_ns_event (nsevent); - return find_window_interested_in_event_mask (current_keyboard_window, event_mask, TRUE); - } - break; + return toplevel; default: /* Ignore everything else. */ @@ -1426,13 +642,42 @@ find_window_for_ns_event (NSEvent *nsevent, return NULL; } -static GdkEvent * -create_button_event (GdkWindow *window, - NSEvent *nsevent, - gint x, - gint y) +static void +fill_crossing_event (GdkWindow *toplevel, + GdkEvent *event, + NSEvent *nsevent, + gint x, + gint y, + gint x_root, + gint y_root, + GdkEventType event_type, + GdkCrossingMode mode, + GdkNotifyType detail) +{ + event->any.type = event_type; + event->crossing.window = toplevel; + event->crossing.subwindow = NULL; + event->crossing.time = get_time_from_ns_event (nsevent); + event->crossing.x = x; + event->crossing.y = y; + event->crossing.x_root = x_root; + event->crossing.y_root = y_root; + event->crossing.mode = mode; + event->crossing.detail = detail; + event->crossing.state = get_keyboard_modifiers_from_ns_event (nsevent); + + /* FIXME: Focus and button state? */ +} + +static void +fill_button_event (GdkWindow *window, + GdkEvent *event, + NSEvent *nsevent, + gint x, + gint y, + gint x_root, + gint y_root) { - GdkEvent *event; GdkEventType type; gint state; gint button; @@ -1458,110 +703,105 @@ create_button_event (GdkWindow *window, button = get_mouse_button_from_ns_event (nsevent); - event = gdk_event_new (type); + event->any.type = type; event->button.window = window; event->button.time = get_time_from_ns_event (nsevent); event->button.x = x; event->button.y = y; + event->button.x_root = x_root; + event->button.y_root = y_root; /* FIXME event->axes */ event->button.state = state; event->button.button = button; event->button.device = _gdk_display->core_pointer; - convert_window_coordinates_to_root (window, x, y, - &event->button.x_root, - &event->button.y_root); - - return event; } -static GdkEvent * -create_motion_event (GdkWindow *window, - NSEvent *nsevent, - gint x, - gint y) +static void +fill_motion_event (GdkWindow *window, + GdkEvent *event, + NSEvent *nsevent, + gint x, + gint y, + gint x_root, + gint y_root) { - GdkEvent *event; - GdkEventType type; - GdkModifierType state = 0; + GdkModifierType state; + + state = get_keyboard_modifiers_from_ns_event (nsevent); switch ([nsevent type]) { case NSLeftMouseDragged: case NSRightMouseDragged: case NSOtherMouseDragged: - state = get_mouse_button_modifiers_from_ns_event (nsevent); - /* Fall through */ - case NSMouseMoved: - type = GDK_MOTION_NOTIFY; + state |= get_mouse_button_modifiers_from_ns_event (nsevent); + break; + + case NSMouseMoved: break; - default: - g_assert_not_reached (); } - state |= get_keyboard_modifiers_from_ns_event (nsevent); - - event = gdk_event_new (type); + event->any.type = GDK_MOTION_NOTIFY; event->motion.window = window; event->motion.time = get_time_from_ns_event (nsevent); event->motion.x = x; event->motion.y = y; + event->motion.x_root = x_root; + event->motion.y_root = y_root; /* FIXME event->axes */ event->motion.state = state; event->motion.is_hint = FALSE; event->motion.device = _gdk_display->core_pointer; - convert_window_coordinates_to_root (window, x, y, - &event->motion.x_root, &event->motion.y_root); - - return event; } -static GdkEvent * -create_scroll_event (GdkWindow *window, - NSEvent *nsevent, - GdkScrollDirection direction) +static void +fill_scroll_event (GdkWindow *window, + GdkEvent *event, + NSEvent *nsevent, + gint x, + gint y, + gint x_root, + gint y_root, + GdkScrollDirection direction) { - GdkEvent *event; + GdkWindowObject *private; NSPoint point; - - event = gdk_event_new (GDK_SCROLL); - event->scroll.window = window; - event->scroll.time = get_time_from_ns_event (nsevent); + + private = GDK_WINDOW_OBJECT (window); point = [nsevent locationInWindow]; - event->scroll.x = point.x; - event->scroll.y = point.y; - event->scroll.state = get_keyboard_modifiers_from_ns_event (nsevent); - convert_window_coordinates_to_root (window, event->scroll.x, event->scroll.y, - &event->scroll.x_root, - &event->scroll.y_root); + event->any.type = GDK_SCROLL; + event->scroll.window = window; + event->scroll.time = get_time_from_ns_event (nsevent); + event->scroll.x = x; + event->scroll.y = y; + event->scroll.x_root = x_root; + event->scroll.y_root = y_root; + event->scroll.state = get_keyboard_modifiers_from_ns_event (nsevent); event->scroll.direction = direction; event->scroll.device = _gdk_display->core_pointer; - - return event; } -static GdkEvent * -create_key_event (GdkWindow *window, - NSEvent *nsevent, - GdkEventType type) +static void +fill_key_event (GdkWindow *window, + GdkEvent *event, + NSEvent *nsevent, + GdkEventType type) { - GdkEvent *event; GdkEventPrivate *priv; gchar buf[7]; gunichar c = 0; - event = gdk_event_new (type); - priv = (GdkEventPrivate *) event; priv->windowing_data = [nsevent retain]; + event->any.type = type; event->key.window = window; event->key.time = get_time_from_ns_event (nsevent); event->key.state = get_keyboard_modifiers_from_ns_event (nsevent); event->key.hardware_keycode = [nsevent keyCode]; event->key.group = ([nsevent modifierFlags] & NSAlternateKeyMask) ? 1 : 0; - event->key.keyval = GDK_VoidSymbol; gdk_keymap_translate_keyboard_state (NULL, @@ -1620,7 +860,7 @@ create_key_event (GdkWindow *window, if (event->key.keyval != GDK_VoidSymbol) c = gdk_keyval_to_unicode (event->key.keyval); - if (c) + if (c) { gsize bytes_written; gint len; @@ -1658,7 +898,59 @@ create_key_event (GdkWindow *window, event->key.window, event->key.keyval ? gdk_keyval_name (event->key.keyval) : "(none)", event->key.keyval)); - return event; +} + +static gboolean +synthesize_crossing_event (GdkWindow *window, + GdkEvent *event, + NSEvent *nsevent, + gint x, + gint y, + gint x_root, + gint y_root) +{ + GdkWindowObject *private; + + private = GDK_WINDOW_OBJECT (window); + + switch ([nsevent type]) + { + case NSMouseEntered: + /* Enter events are considered always to be from the root window as we + * can't know for sure from what window we enter. + */ + if (!(private->event_mask & GDK_ENTER_NOTIFY_MASK)) + return FALSE; + + fill_crossing_event (window, event, nsevent, + x, y, + x_root, y_root, + GDK_ENTER_NOTIFY, + GDK_CROSSING_NORMAL, + GDK_NOTIFY_ANCESTOR); + return TRUE; + + case NSMouseExited: + /* Exited always is to the root window as far as we are concerned, + * since there is no way to reliably get information about what new + * window is entered when exiting one. + */ + if (!(private->event_mask & GDK_LEAVE_NOTIFY_MASK)) + return FALSE; + + fill_crossing_event (window, event, nsevent, + x, y, + x_root, y_root, + GDK_LEAVE_NOTIFY, + GDK_CROSSING_NORMAL, + GDK_NOTIFY_ANCESTOR); + return TRUE; + + default: + break; + } + + return FALSE; } GdkEventMask @@ -1668,40 +960,38 @@ _gdk_quartz_events_get_current_event_mask (void) } static gboolean -gdk_event_translate (NSEvent *nsevent) +gdk_event_translate (GdkEvent *event, + NSEvent *nsevent) { + NSEventType event_type; NSWindow *nswindow; GdkWindow *window; - GdkFilterReturn result; - GdkEvent *event; int x, y; + int x_root, y_root; + gboolean return_val; /* There is no support for real desktop wide grabs, so we break * grabs when the application loses focus (gets deactivated). */ - if ([nsevent type] == NSAppKitDefined) + event_type = [nsevent type]; + if (event_type == NSAppKitDefined) { if ([nsevent subtype] == NSApplicationDeactivatedEventType) - break_all_grabs (); + break_all_grabs (get_time_from_ns_event (nsevent)); /* This could potentially be used to break grabs when clicking * on the title. The subtype 20 is undocumented so it's probably * not a good idea: else if (subtype == 20) break_all_grabs (); */ - } - /* Handle our generated "fake" crossing events. */ - if ([nsevent type] == NSApplicationDefined && - [nsevent subtype] == GDK_QUARTZ_EVENT_SUBTYPE_FAKE_CROSSING) - { - _gdk_quartz_events_trigger_crossing_events (FALSE); - return TRUE; + /* Leave all AppKit events to AppKit. */ + return FALSE; } /* Keep track of button state, since we don't get that information * for key events. */ - switch ([nsevent type]) + switch (event_type) { case NSLeftMouseDown: case NSRightMouseDown: @@ -1717,21 +1007,21 @@ gdk_event_translate (NSEvent *nsevent) break; } - nswindow = [nsevent window]; - - /* Apply any global filters. */ if (_gdk_default_filters) { - result = apply_filters (NULL, nsevent, _gdk_default_filters); + /* Apply global filters */ + GdkFilterReturn result; - /* If result is GDK_FILTER_CONTINUE, we continue as if nothing - * happened. If it is GDK_FILTER_REMOVE, - * we return TRUE and won't send the message to Quartz. - */ - if (result == GDK_FILTER_REMOVE) - return TRUE; + result = gdk_event_apply_filters (nsevent, event, _gdk_default_filters); + if (result != GDK_FILTER_CONTINUE) + { + return_val = (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE; + goto done; + } } + nswindow = [nsevent window]; + /* Ignore events for no window or ones not created by GDK. */ if (!nswindow || ![[nswindow contentView] isKindOfClass:[GdkQuartzView class]]) return FALSE; @@ -1742,84 +1032,86 @@ gdk_event_translate (NSEvent *nsevent) */ if ([(GdkQuartzWindow *)nswindow isInMove]) { - break_all_grabs (); + break_all_grabs (get_time_from_ns_event (nsevent)); return FALSE; } - /* Take care of NSMouseEntered/Exited events and mouse movements - * events and emit the right GDK crossing events. - */ - synthesize_crossing_events_for_ns_event (nsevent); - /* Find the right GDK window to send the event to, taking grabs and * event masks into consideration. */ - window = find_window_for_ns_event (nsevent, &x, &y); + window = find_window_for_ns_event (nsevent, &x, &y, &x_root, &y_root); if (!window) return FALSE; /* Apply any window filters. */ - result = apply_filters (window, nsevent, ((GdkWindowObject *) window)->filters); - if (result == GDK_FILTER_REMOVE) - return TRUE; - - /* We need the appliction to be activated on clicks so that popups - * like context menus get events routed properly. This is handled - * automatically for left mouse button presses but not other - * buttons, so we do it here. - */ - if ([nsevent type] == NSRightMouseDown || [nsevent type] == NSOtherMouseDown) + if (GDK_IS_WINDOW (window)) { + GdkWindowObject *filter_private = (GdkWindowObject *) window; + GdkFilterReturn result; + + if (filter_private->filters) + { + g_object_ref (window); + + result = gdk_event_apply_filters (nsevent, event, filter_private->filters); + + g_object_unref (window); + + if (result != GDK_FILTER_CONTINUE) + { + return_val = (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE; + goto done; + } + } + } + + /* If the app is not active leave the event to AppKit so the window gets + * focused correctly and don't do click-through (so we behave like most + * native apps). If the app is active, we focus the window and then handle + * the event, also to match native apps. + */ + if ((event_type == NSRightMouseDown || + event_type == NSOtherMouseDown || + event_type == NSLeftMouseDown)) + { + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl); + if (![NSApp isActive]) - [NSApp activateIgnoringOtherApps:YES]; + { + [NSApp activateIgnoringOtherApps:YES]; + return FALSE; + } + else if (![impl->toplevel isKeyWindow]) + { + GdkPointerGrabInfo *grab; + + grab = _gdk_display_get_last_pointer_grab (_gdk_display); + if (!grab) + [impl->toplevel makeKeyWindow]; + } } current_event_mask = get_event_mask_from_ns_event (nsevent); - switch ([nsevent type]) + return_val = TRUE; + + switch (event_type) { case NSLeftMouseDown: case NSRightMouseDown: case NSOtherMouseDown: - { - GdkEventMask event_mask; - - /* Emulate implicit grab, when the window has both PRESS and RELEASE - * in its mask, like X. - */ - event_mask = (GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK); - if (!_gdk_quartz_pointer_grab_window && - (GDK_WINDOW_OBJECT (window)->event_mask & event_mask) == event_mask) - { - pointer_grab_internal (window, FALSE, - GDK_WINDOW_OBJECT (window)->event_mask, - NULL, NULL, TRUE); - } - } - - event = create_button_event (window, nsevent, x, y); - append_event (event); - - _gdk_event_button_generate (_gdk_display, event); - break; - case NSLeftMouseUp: case NSRightMouseUp: case NSOtherMouseUp: - event = create_button_event (window, nsevent, x, y); - append_event (event); - - /* Ungrab implicit grab */ - if (_gdk_quartz_pointer_grab_window && pointer_grab_implicit) - pointer_ungrab_internal (TRUE); + fill_button_event (window, event, nsevent, x, y, x_root, y_root); break; case NSLeftMouseDragged: case NSRightMouseDragged: case NSOtherMouseDragged: case NSMouseMoved: - event = create_motion_event (window, nsevent, x, y); - append_event (event); + fill_motion_event (window, event, nsevent, x, y, x_root, y_root); break; case NSScrollWheel: @@ -1828,51 +1120,33 @@ gdk_event_translate (NSEvent *nsevent) float dy = [nsevent deltaY]; GdkScrollDirection direction; - /* The delta is how much the mouse wheel has moved. Since there's no such thing in GTK+ - * we accomodate by sending a different number of scroll wheel events. - */ + if (dy != 0) + { + if (dy < 0.0) + direction = GDK_SCROLL_DOWN; + else + direction = GDK_SCROLL_UP; - /* First do y events */ - if (dy < 0.0) - { - dy = -dy; - direction = GDK_SCROLL_DOWN; - } - else - direction = GDK_SCROLL_UP; + fill_scroll_event (window, event, nsevent, x, y, x_root, y_root, direction); + } - while (dy > 0.0) - { - event = create_scroll_event (window, nsevent, direction); - append_event (event); - dy--; - - /* Ignore the delta for now, things get too slow when the events queue up. */ - break; - } - - /* Now do x events */ - if (dx < 0.0) - { - dx = -dx; - direction = GDK_SCROLL_RIGHT; - } - else - direction = GDK_SCROLL_LEFT; - - while (dx > 0.0) - { - event = create_scroll_event (window, nsevent, direction); - append_event (event); - dx--; - - /* Ignore the delta for now, things get too slow when the events queue up. */ - break; - } + if (dx != 0) + { + if (dx < 0.0) + direction = GDK_SCROLL_RIGHT; + else + direction = GDK_SCROLL_LEFT; + fill_scroll_event (window, event, nsevent, x, y, x_root, y_root, direction); + } } break; + case NSMouseEntered: + case NSMouseExited: + return_val = synthesize_crossing_event (window, event, nsevent, x, y, x_root, y_root); + break; + case NSKeyDown: case NSKeyUp: case NSFlagsChanged: @@ -1881,38 +1155,75 @@ gdk_event_translate (NSEvent *nsevent) type = _gdk_quartz_keys_event_type (nsevent); if (type == GDK_NOTHING) - return FALSE; - - event = create_key_event (window, nsevent, type); - append_event (event); - return TRUE; + return_val = FALSE; + else + fill_key_event (window, event, nsevent, type); } break; default: /* Ignore everything elsee. */ + return_val = FALSE; break; } - return FALSE; + done: + if (return_val) + { + if (event->any.window) + g_object_ref (event->any.window); + if (((event->any.type == GDK_ENTER_NOTIFY) || + (event->any.type == GDK_LEAVE_NOTIFY)) && + (event->crossing.subwindow != NULL)) + g_object_ref (event->crossing.subwindow); + } + else + { + /* Mark this event as having no resources to be freed */ + event->any.window = NULL; + event->any.type = GDK_NOTHING; + } + + return return_val; } void _gdk_events_queue (GdkDisplay *display) { - NSEvent *event; + NSEvent *nsevent; - event = _gdk_quartz_event_loop_get_pending (); - if (event) + nsevent = _gdk_quartz_event_loop_get_pending (); + if (nsevent) { - if (!gdk_event_translate (event)) + GdkEvent *event; + GList *node; + + event = gdk_event_new (GDK_NOTHING); + + event->any.window = NULL; + event->any.send_event = FALSE; + + ((GdkEventPrivate *)event)->flags |= GDK_EVENT_PENDING; + + node = _gdk_event_queue_append (display, event); + + if (gdk_event_translate (event, nsevent)) { + ((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING; + _gdk_windowing_got_event (display, node, event, 0); + } + else + { + _gdk_event_queue_remove_link (display, node); + g_list_free_1 (node); + gdk_event_free (event); + GDK_THREADS_LEAVE (); - [NSApp sendEvent:event]; + [NSApp sendEvent:nsevent]; GDK_THREADS_ENTER (); } - _gdk_quartz_event_loop_release_event (event); + _gdk_quartz_event_loop_release_event (nsevent); } } @@ -1922,7 +1233,7 @@ gdk_flush (void) /* Not supported. */ } -void +void gdk_display_add_client_message_filter (GdkDisplay *display, GdkAtom message_type, GdkFilterFunc func, @@ -1931,7 +1242,7 @@ gdk_display_add_client_message_filter (GdkDisplay *display, /* Not supported. */ } -void +void gdk_add_client_message_filter (GdkAtom message_type, GdkFilterFunc func, gpointer data) diff --git a/gdk/quartz/gdkgc-quartz.c b/gdk/quartz/gdkgc-quartz.c index ea77379101..c4da89328c 100644 --- a/gdk/quartz/gdkgc-quartz.c +++ b/gdk/quartz/gdkgc-quartz.c @@ -208,7 +208,8 @@ _gdk_quartz_gc_new (GdkDrawable *drawable, void _gdk_windowing_gc_set_clip_region (GdkGC *gc, - const GdkRegion *region) + const GdkRegion *region, + gboolean reset_origin) { GdkGCQuartz *private = GDK_GC_QUARTZ (gc); @@ -224,8 +225,11 @@ _gdk_windowing_gc_set_clip_region (GdkGC *gc, private->have_clip_region = region != NULL; - gc->clip_x_origin = 0; - gc->clip_y_origin = 0; + if (reset_origin) + { + gc->clip_x_origin = 0; + gc->clip_y_origin = 0; + } } void @@ -281,7 +285,6 @@ gdk_quartz_draw_tiled_pattern (void *info, CGContextRef context) { GdkGC *gc = GDK_GC (info); - GdkGCQuartz *private = GDK_GC_QUARTZ (gc); CGImageRef pattern_image; size_t width, height; diff --git a/gdk/quartz/gdkgeometry-quartz.c b/gdk/quartz/gdkgeometry-quartz.c index 921128aec5..06a31f10cc 100644 --- a/gdk/quartz/gdkgeometry-quartz.c +++ b/gdk/quartz/gdkgeometry-quartz.c @@ -23,68 +23,43 @@ #include "gdkprivate-quartz.h" void -_gdk_quartz_window_scroll (GdkWindow *window, - gint dx, - gint dy) +_gdk_quartz_window_queue_translation (GdkWindow *window, + GdkGC *gc, + GdkRegion *area, + gint dx, + gint dy) { - NSRect visible_nsrect; - GdkRectangle visible_rect, scrolled_rect; - GdkRegion *visible_region, *scrolled_region; + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowImplQuartz *impl = (GdkWindowImplQuartz *)private->impl; + + int i, n_rects; + GdkRegion *intersection; GdkRectangle *rects; - gint n_rects, i; - GdkWindowObject *private = GDK_WINDOW_OBJECT (window); - GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl); - GList *list; - /* Move the current invalid region */ - if (private->update_area) - gdk_region_offset (private->update_area, dx, dy); + /* We will intersect the known region that needs display with the given + * area. This intersection will be translated by dx, dy. For the end + * result, we will also set that it needs display. + */ - visible_nsrect = [impl->view visibleRect]; + if (!impl->needs_display_region) + return; - visible_rect.x = visible_nsrect.origin.x; - visible_rect.y = visible_nsrect.origin.y; - visible_rect.width = visible_nsrect.size.width; - visible_rect.height = visible_nsrect.size.height; - - scrolled_rect = visible_rect; - scrolled_rect.x += dx; - scrolled_rect.y += dy; - - gdk_rectangle_intersect (&visible_rect, &scrolled_rect, &scrolled_rect); - - visible_region = gdk_region_rectangle (&visible_rect); - scrolled_region = gdk_region_rectangle (&scrolled_rect); + intersection = gdk_region_copy (impl->needs_display_region); + gdk_region_intersect (intersection, area); + gdk_region_offset (intersection, dx, dy); - gdk_region_subtract (visible_region, scrolled_region); + gdk_region_get_rectangles (intersection, &rects, &n_rects); - [impl->view scrollRect:[impl->view bounds] by:NSMakeSize(dx, dy)]; - - gdk_region_get_rectangles (visible_region, &rects, &n_rects); for (i = 0; i < n_rects; i++) - [impl->view setNeedsDisplayInRect:NSMakeRect (rects[i].x, rects[i].y, rects[i].width, rects[i].height)]; - + _gdk_quartz_window_set_needs_display_in_rect (window, &rects[i]); + g_free (rects); - - gdk_region_destroy (visible_region); - gdk_region_destroy (scrolled_region); - - /* Move child windows */ - for (list = private->children; list; list = list->next) - { - GdkWindowObject *child = GDK_WINDOW_OBJECT (list->data); - - gdk_window_move (list->data, - child->x + dx, - child->y + dy); - } + gdk_region_destroy (intersection); } -void -_gdk_quartz_window_move_region (GdkWindow *window, - const GdkRegion *region, - gint dx, - gint dy) +gboolean +_gdk_quartz_window_queue_antiexpose (GdkWindow *window, + GdkRegion *area) { - /* FIXME: Implement */ + return FALSE; } diff --git a/gdk/quartz/gdkinput.c b/gdk/quartz/gdkinput.c index 280af5e303..657d43590b 100644 --- a/gdk/quartz/gdkinput.c +++ b/gdk/quartz/gdkinput.c @@ -206,7 +206,7 @@ gdk_device_get_history (GdkDevice *device, gint *n_events) { g_return_val_if_fail (window != NULL, FALSE); - g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE); + g_return_val_if_fail (GDK_WINDOW_IS_QUARTZ (window), FALSE); g_return_val_if_fail (events != NULL, FALSE); g_return_val_if_fail (n_events != NULL, FALSE); @@ -262,7 +262,7 @@ gdk_input_set_extension_events (GdkWindow *window, gint mask, GdkInputWindow *iw; g_return_if_fail (window != NULL); - g_return_if_fail (GDK_IS_WINDOW (window)); + g_return_if_fail (GDK_WINDOW_IS_QUARTZ (window)); window_private = (GdkWindowObject*) window; diff --git a/gdk/quartz/gdkinputprivate.h b/gdk/quartz/gdkinputprivate.h index 8dbfa0b68a..5ec4ee99b5 100644 --- a/gdk/quartz/gdkinputprivate.h +++ b/gdk/quartz/gdkinputprivate.h @@ -35,7 +35,6 @@ typedef struct _GdkAxisInfo GdkAxisInfo; typedef struct _GdkInputVTable GdkInputVTable; typedef struct _GdkDevicePrivate GdkDevicePrivate; -typedef struct _GdkInputWindow GdkInputWindow; struct _GdkInputVTable { gint (*set_mode) (guint32 deviceid, GdkInputMode mode); diff --git a/gdk/quartz/gdkpixmap-quartz.c b/gdk/quartz/gdkpixmap-quartz.c index e55ff9d1aa..a74348089d 100644 --- a/gdk/quartz/gdkpixmap-quartz.c +++ b/gdk/quartz/gdkpixmap-quartz.c @@ -137,10 +137,10 @@ data_provider_release (void *info, const void *data, size_t size) } GdkPixmap* -gdk_pixmap_new (GdkDrawable *drawable, - gint width, - gint height, - gint depth) +_gdk_pixmap_new (GdkDrawable *drawable, + gint width, + gint height, + gint depth) { GdkPixmap *pixmap; GdkDrawableImplQuartz *draw_impl; @@ -224,10 +224,10 @@ gdk_pixmap_new (GdkDrawable *drawable, } GdkPixmap * -gdk_bitmap_create_from_data (GdkDrawable *window, - const gchar *data, - gint width, - gint height) +_gdk_bitmap_create_from_data (GdkDrawable *window, + const gchar *data, + gint width, + gint height) { GdkPixmap *pixmap; GdkPixmapImplQuartz *impl; @@ -264,13 +264,13 @@ gdk_bitmap_create_from_data (GdkDrawable *window, } GdkPixmap* -gdk_pixmap_create_from_data (GdkDrawable *drawable, - const gchar *data, - gint width, - gint height, - gint depth, - const GdkColor *fg, - const GdkColor *bg) +_gdk_pixmap_create_from_data (GdkDrawable *drawable, + const gchar *data, + gint width, + gint height, + gint depth, + const GdkColor *fg, + const GdkColor *bg) { /* FIXME: Implement */ return NULL; diff --git a/gdk/quartz/gdkprivate-quartz.h b/gdk/quartz/gdkprivate-quartz.h index efffe6b62b..52834b36d5 100644 --- a/gdk/quartz/gdkprivate-quartz.h +++ b/gdk/quartz/gdkprivate-quartz.h @@ -102,6 +102,8 @@ extern GdkWindow *_gdk_root; extern GdkDragContext *_gdk_quartz_drag_source_context; +#define GDK_WINDOW_IS_QUARTZ(win) (GDK_IS_WINDOW_IMPL_QUARTZ (((GdkWindowObject *)win)->impl)) + /* Initialization */ void _gdk_windowing_window_init (void); void _gdk_events_init (void); @@ -147,23 +149,18 @@ void _gdk_quartz_window_did_resign_main (GdkWindow *window); void _gdk_quartz_window_debug_highlight (GdkWindow *window, gint number); +void _gdk_quartz_window_set_needs_display_in_rect (GdkWindow *window, + GdkRectangle *rect); + /* Events */ typedef enum { - GDK_QUARTZ_EVENT_SUBTYPE_EVENTLOOP, - GDK_QUARTZ_EVENT_SUBTYPE_FAKE_CROSSING + GDK_QUARTZ_EVENT_SUBTYPE_EVENTLOOP } GdkQuartzEventSubType; void _gdk_quartz_events_update_focus_window (GdkWindow *new_window, gboolean got_focus); -GdkWindow * _gdk_quartz_events_get_mouse_window (gboolean consider_grabs); -void _gdk_quartz_events_update_mouse_window (GdkWindow *window); -void _gdk_quartz_events_update_cursor (GdkWindow *window); -void _gdk_quartz_events_send_map_events (GdkWindow *window); +void _gdk_quartz_events_send_map_event (GdkWindow *window); GdkEventMask _gdk_quartz_events_get_current_event_mask (void); -void _gdk_quartz_events_trigger_crossing_events(gboolean defer_to_mainloop); - -extern GdkWindow *_gdk_quartz_keyboard_grab_window; -extern GdkWindow *_gdk_quartz_pointer_grab_window; /* Event loop */ gboolean _gdk_quartz_event_loop_check_pending (void); @@ -186,14 +183,18 @@ gboolean _gdk_quartz_keys_is_modifier (guint keycode); /* Drawable */ void _gdk_quartz_drawable_finish (GdkDrawable *drawable); +void _gdk_quartz_drawable_flush (GdkDrawable *drawable); /* Geometry */ void _gdk_quartz_window_scroll (GdkWindow *window, gint dx, gint dy); -void _gdk_quartz_window_move_region (GdkWindow *window, - const GdkRegion *region, - gint dx, - gint dy); +void _gdk_quartz_window_queue_translation (GdkWindow *window, + GdkGC *gc, + GdkRegion *area, + gint dx, + gint dy); +gboolean _gdk_quartz_window_queue_antiexpose (GdkWindow *window, + GdkRegion *area); #endif /* __GDK_PRIVATE_QUARTZ_H__ */ diff --git a/gdk/quartz/gdkscreen-quartz.c b/gdk/quartz/gdkscreen-quartz.c index 050267cc9b..30cd73edda 100644 --- a/gdk/quartz/gdkscreen-quartz.c +++ b/gdk/quartz/gdkscreen-quartz.c @@ -82,6 +82,13 @@ gdk_screen_set_default_colormap (GdkScreen *screen, g_object_unref (old_colormap); } +/* FIXME: note on the get_width() and the get_height() methods. For + * now we only support screen layouts where the screens are laid out + * horizontally. Mac OS X also supports laying out the screens vertically + * and the screens having "non-standard" offsets from eachother. In the + * future we need a much more sophiscated algorithm to translate these + * layouts to GDK coordinate space and GDK screen layout. + */ gint gdk_screen_get_width (GdkScreen *screen) { @@ -221,6 +228,8 @@ screen_get_monitor_geometry (GdkScreen *screen, NSArray *array; NSScreen *nsscreen; NSRect rect; + NSRect largest_rect; + int i; GDK_QUARTZ_ALLOC_POOL; @@ -229,10 +238,31 @@ screen_get_monitor_geometry (GdkScreen *screen, rect = [nsscreen frame]; dest->x = rect.origin.x; - dest->y = rect.origin.y; dest->width = rect.size.width; dest->height = rect.size.height; + /* FIXME: as stated above the get_width() and get_height() functions + * in this file, we only support horizontal screen layouts for now. + */ + + /* Find the monitor with the largest height. All monitors should be + * offset to this one in the GDK screen space instead of offset to + * the screen with the menu bar. + */ + largest_rect = [[array objectAtIndex:0] frame]; + for (i = 1; i < [array count]; i++) + { + NSRect rect = [[array objectAtIndex:i] frame]; + + if (rect.size.height > largest_rect.size.height) + largest_rect = [[array objectAtIndex:i] frame]; + } + + if (largest_rect.size.height - rect.size.height == 0) + dest->y = 0; + else + dest->y = largest_rect.size.height - rect.size.height + largest_rect.origin.y; + if (in_mm) { dest->x = get_mm_from_pixels (nsscreen, dest->x); diff --git a/gdk/quartz/gdkwindow-quartz.c b/gdk/quartz/gdkwindow-quartz.c index c6ed9cb9e6..4764498340 100644 --- a/gdk/quartz/gdkwindow-quartz.c +++ b/gdk/quartz/gdkwindow-quartz.c @@ -28,8 +28,8 @@ static gpointer parent_class; -static GSList *update_windows; -static guint update_idle; +static GSList *update_nswindows; +static gboolean in_process_all_updates = FALSE; static GSList *main_window_stack; @@ -48,9 +48,10 @@ static void clear_toplevel_order (void); static FullscreenSavedGeometry *get_fullscreen_geometry (GdkWindow *window); -#define WINDOW_IS_TOPLEVEL(window) \ - (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \ - GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN) +#define WINDOW_IS_TOPLEVEL(window) \ + (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \ + GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN && \ + GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN) static void gdk_window_impl_iface_init (GdkWindowImplIface *iface); @@ -76,19 +77,6 @@ gdk_quartz_window_get_nswindow (GdkWindow *window) return ((GdkWindowImplQuartz *)private->impl)->toplevel; } -static void -gdk_window_impl_quartz_get_size (GdkDrawable *drawable, - gint *width, - gint *height) -{ - g_return_if_fail (GDK_IS_WINDOW_IMPL_QUARTZ (drawable)); - - if (width) - *width = GDK_WINDOW_IMPL_QUARTZ (drawable)->width; - if (height) - *height = GDK_WINDOW_IMPL_QUARTZ (drawable)->height; -} - static CGContextRef gdk_window_impl_quartz_get_context (GdkDrawable *drawable, gboolean antialias) @@ -104,7 +92,7 @@ gdk_window_impl_quartz_get_context (GdkDrawable *drawable, * is needed when called from outside "real" expose events, for * example for synthesized expose events when realizing windows * and for widgets that send fake expose events like the arrow - * buttons in spinbuttons. + * buttons in spinbuttons or the position marker in rulers. */ if (window_impl->in_paint_rect_count == 0) { @@ -150,54 +138,44 @@ gdk_window_impl_quartz_get_context (GdkDrawable *drawable, return cg_context; } -static GdkRegion* -gdk_window_impl_quartz_get_visible_region (GdkDrawable *drawable) +static void +check_grab_unmap (GdkWindow *window) { - GdkWindowObject *private = GDK_WINDOW_OBJECT (GDK_DRAWABLE_IMPL_QUARTZ (drawable)->wrapper); - GdkRectangle rect; - GdkWindowImplQuartz *impl; - GList *windows = NULL, *l; + GdkDisplay *display = gdk_drawable_get_display (window); - /* FIXME: The clip rectangle should really be cached - * and recalculated when the window rectangle changes. - */ - while (private) + _gdk_display_end_pointer_grab (display, 0, window, TRUE); + + if (display->keyboard_grab.window) { - windows = g_list_prepend (windows, private); + GdkWindowObject *private = GDK_WINDOW_OBJECT (window); + GdkWindowObject *tmp = GDK_WINDOW_OBJECT (display->keyboard_grab.window); - if (private->parent == GDK_WINDOW_OBJECT (_gdk_root)) - break; + while (tmp && tmp != private) + tmp = tmp->parent; - private = private->parent; + if (tmp) + _gdk_display_unset_has_keyboard_grab (display, TRUE); + } +} + +static void +check_grab_destroy (GdkWindow *window) +{ + GdkDisplay *display = gdk_drawable_get_display (window); + GdkPointerGrabInfo *grab; + + /* Make sure there is no lasting grab in this native window */ + grab = _gdk_display_get_last_pointer_grab (display); + if (grab && grab->native_window == window) + { + /* Serials are always 0 in quartz, but for clarity: */ + grab->serial_end = grab->serial_start; + grab->implicit_ungrab = TRUE; } - /* Get rectangle for toplevel window */ - private = GDK_WINDOW_OBJECT (windows->data); - impl = GDK_WINDOW_IMPL_QUARTZ (private->impl); - - rect.x = 0; - rect.y = 0; - rect.width = impl->width; - rect.height = impl->height; - - /* Skip toplevel window since we have its rect */ - for (l = windows->next; l; l = l->next) - { - private = GDK_WINDOW_OBJECT (l->data); - impl = GDK_WINDOW_IMPL_QUARTZ (private->impl); - GdkRectangle tmp_rect; - - tmp_rect.x = -MIN (0, private->x - rect.x); - tmp_rect.y = -MIN (0, private->y - rect.y); - tmp_rect.width = MIN (rect.width, impl->width + private->x - rect.x) - MAX (0, private->x - rect.x); - tmp_rect.height = MIN (rect.height, impl->height + private->y - rect.y) - MAX (0, private->y - rect.y); - - rect = tmp_rect; - } - - g_list_free (windows); - - return gdk_region_rectangle (&rect); + if (window == display->keyboard_grab.native_window && + display->keyboard_grab.window != NULL) + _gdk_display_unset_has_keyboard_grab (display, TRUE); } static void @@ -205,8 +183,7 @@ gdk_window_impl_quartz_finalize (GObject *object) { GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (object); - if (impl->nscursor) - [impl->nscursor release]; + check_grab_destroy (GDK_DRAWABLE_IMPL_QUARTZ (object)->wrapper); if (impl->paint_clip_region) gdk_region_destroy (impl->paint_clip_region); @@ -220,56 +197,58 @@ gdk_window_impl_quartz_finalize (GObject *object) static void gdk_window_impl_quartz_class_init (GdkWindowImplQuartzClass *klass) { - GdkDrawableImplQuartzClass *drawable_quartz_class = GDK_DRAWABLE_IMPL_QUARTZ_CLASS (klass); - GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass); + GdkDrawableImplQuartzClass *drawable_quartz_class = GDK_DRAWABLE_IMPL_QUARTZ_CLASS (klass); parent_class = g_type_class_peek_parent (klass); object_class->finalize = gdk_window_impl_quartz_finalize; - drawable_class->get_size = gdk_window_impl_quartz_get_size; - drawable_quartz_class->get_context = gdk_window_impl_quartz_get_context; - - /* Visible and clip regions are the same */ - drawable_class->get_clip_region = gdk_window_impl_quartz_get_visible_region; - drawable_class->get_visible_region = gdk_window_impl_quartz_get_visible_region; } static void gdk_window_impl_quartz_init (GdkWindowImplQuartz *impl) { - impl->width = 1; - impl->height = 1; impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL; } static void gdk_window_impl_quartz_begin_paint_region (GdkPaintable *paintable, + GdkWindow *window, const GdkRegion *region) { GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (paintable); - GdkDrawableImplQuartz *drawable_impl; + GdkWindowObject *private = (GdkWindowObject*)window; int n_rects; - GdkRectangle *rects; + GdkRectangle *rects = NULL; GdkPixmap *bg_pixmap; - GdkWindow *window; + GdkRegion *clipped_and_offset_region; + gboolean free_clipped_and_offset_region = TRUE; - drawable_impl = GDK_DRAWABLE_IMPL_QUARTZ (impl); - bg_pixmap = GDK_WINDOW_OBJECT (drawable_impl->wrapper)->bg_pixmap; + bg_pixmap = private->bg_pixmap; + + clipped_and_offset_region = gdk_region_copy (region); + + gdk_region_intersect (clipped_and_offset_region, + private->clip_region_with_children); + gdk_region_offset (clipped_and_offset_region, + private->abs_x, private->abs_y); if (impl->begin_paint_count == 0) - impl->paint_clip_region = gdk_region_copy (region); + { + impl->paint_clip_region = clipped_and_offset_region; + free_clipped_and_offset_region = FALSE; + } else - gdk_region_union (impl->paint_clip_region, region); + gdk_region_union (impl->paint_clip_region, clipped_and_offset_region); impl->begin_paint_count++; if (bg_pixmap == GDK_NO_BG) - return; + goto done; - gdk_region_get_rectangles (region, &rects, &n_rects); + gdk_region_get_rectangles (clipped_and_offset_region, &rects, &n_rects); if (bg_pixmap == NULL) { @@ -278,9 +257,9 @@ gdk_window_impl_quartz_begin_paint_region (GdkPaintable *paintable, gint i; cg_context = gdk_quartz_drawable_get_context (GDK_DRAWABLE (impl), FALSE); - _gdk_quartz_colormap_get_rgba_from_pixel (gdk_drawable_get_colormap (drawable_impl->wrapper), - GDK_WINDOW_OBJECT (drawable_impl->wrapper)->bg_color.pixel, - &r, &g, &b, &a); + _gdk_quartz_colormap_get_rgba_from_pixel (gdk_drawable_get_colormap (window), + private->bg_color.pixel, + &r, &g, &b, &a); CGContextSetRGBFillColor (cg_context, r, g, b, a); for (i = 0; i < n_rects; i++) @@ -301,7 +280,6 @@ gdk_window_impl_quartz_begin_paint_region (GdkPaintable *paintable, x_offset = y_offset = 0; - window = GDK_WINDOW (drawable_impl->wrapper); while (window && bg_pixmap == GDK_PARENT_RELATIVE_BG) { /* If this window should have the same background as the parent, @@ -319,8 +297,7 @@ gdk_window_impl_quartz_begin_paint_region (GdkPaintable *paintable, /* Parent relative background but the parent doesn't have a * pixmap. */ - g_free (rects); - return; + goto done; } /* Note: There should be a CG API to draw tiled images, we might @@ -350,6 +327,9 @@ gdk_window_impl_quartz_begin_paint_region (GdkPaintable *paintable, g_object_unref (gc); } + done: + if (free_clipped_and_offset_region) + gdk_region_destroy (clipped_and_offset_region); g_free (rects); } @@ -367,155 +347,112 @@ gdk_window_impl_quartz_end_paint (GdkPaintable *paintable) } } -static void -gdk_window_quartz_process_updates_internal (GdkWindow *window) +void +_gdk_quartz_window_set_needs_display_in_rect (GdkWindow *window, + GdkRectangle *rect) { - GdkWindowObject *private = (GdkWindowObject *) window; - GdkWindowImplQuartz *impl = (GdkWindowImplQuartz *) private->impl; - - if (private->update_area) - { - int i, n_rects; - GdkRectangle *rects; + GdkWindowObject *private; + GdkWindowImplQuartz *impl; - gdk_region_get_rectangles (private->update_area, &rects, &n_rects); + private = GDK_WINDOW_OBJECT (window); + impl = GDK_WINDOW_IMPL_QUARTZ (private->impl); - gdk_region_destroy (private->update_area); - private->update_area = NULL; + if (!impl->needs_display_region) + impl->needs_display_region = gdk_region_new (); - for (i = 0; i < n_rects; i++) - { - [impl->view setNeedsDisplayInRect:NSMakeRect (rects[i].x, rects[i].y, - rects[i].width, rects[i].height)]; - } + gdk_region_union_with_rect (impl->needs_display_region, rect); - [impl->view displayIfNeeded]; + [impl->view setNeedsDisplayInRect:NSMakeRect (rect->x, rect->y, + rect->width, rect->height)]; - g_free (rects); - } } -static void -gdk_window_quartz_process_all_updates (void) +void +_gdk_windowing_window_process_updates_recurse (GdkWindow *window, + GdkRegion *region) { - GSList *old_update_windows = update_windows; - GSList *tmp_list = update_windows; - GSList *nswindows; + int i, n_rects; + GdkRectangle *rects; - update_idle = 0; - update_windows = NULL; - nswindows = NULL; - - g_slist_foreach (old_update_windows, (GFunc) g_object_ref, NULL); - - GDK_QUARTZ_ALLOC_POOL; - - while (tmp_list) + /* Make sure to only flush each toplevel at most once if we're called + * from process_all_updates. + */ + if (in_process_all_updates) { - GdkWindow *window = tmp_list->data; GdkWindow *toplevel; - /* Only flush each toplevel at most once. */ toplevel = gdk_window_get_toplevel (window); if (toplevel) { - GdkWindowObject *private; - GdkWindowImplQuartz *impl; + GdkWindowObject *toplevel_private; + GdkWindowImplQuartz *toplevel_impl; NSWindow *nswindow; - private = (GdkWindowObject *) toplevel; - impl = (GdkWindowImplQuartz *) private->impl; - nswindow = impl->toplevel; + toplevel_private = (GdkWindowObject *)toplevel; + toplevel_impl = (GdkWindowImplQuartz *)toplevel_private->impl; + nswindow = toplevel_impl->toplevel; + /* In theory, we could skip the flush disabling, since we only + * have one NSView. + */ if (nswindow && ![nswindow isFlushWindowDisabled]) { + [nswindow retain]; [nswindow disableFlushWindow]; - nswindows = g_slist_prepend (nswindows, nswindow); + update_nswindows = g_slist_prepend (update_nswindows, nswindow); } } - - gdk_window_quartz_process_updates_internal (tmp_list->data); - - g_object_unref (tmp_list->data); - tmp_list = tmp_list->next; } - tmp_list = nswindows; - while (tmp_list) + gdk_region_get_rectangles (region, &rects, &n_rects); + + for (i = 0; i < n_rects; i++) + _gdk_quartz_window_set_needs_display_in_rect (window, &rects[i]); + + g_free (rects); + + /* NOTE: I'm not sure if we should displayIfNeeded here. It slows down a + * lot (since it triggers the beam syncing) and things seem to work + * without it. + */ +} + +void +_gdk_windowing_before_process_all_updates (void) +{ + in_process_all_updates = TRUE; + + NSDisableScreenUpdates (); +} + +void +_gdk_windowing_after_process_all_updates (void) +{ + GSList *old_update_nswindows = update_nswindows; + GSList *tmp_list = update_nswindows; + + update_nswindows = NULL; + + while (tmp_list) { NSWindow *nswindow = tmp_list->data; + [[nswindow contentView] displayIfNeeded]; + + _gdk_quartz_drawable_flush (NULL); + [nswindow enableFlushWindow]; [nswindow flushWindow]; + [nswindow release]; tmp_list = tmp_list->next; } - - GDK_QUARTZ_RELEASE_POOL; - g_slist_free (old_update_windows); - g_slist_free (nswindows); -} + g_slist_free (old_update_nswindows); -static gboolean -gdk_window_quartz_update_idle (gpointer data) -{ - gdk_window_quartz_process_all_updates (); + in_process_all_updates = FALSE; - return FALSE; -} - -static void -gdk_window_impl_quartz_invalidate_maybe_recurse (GdkPaintable *paintable, - const GdkRegion *region, - gboolean (*child_func) (GdkWindow *, gpointer), - gpointer user_data) -{ - GdkWindowImplQuartz *window_impl = GDK_WINDOW_IMPL_QUARTZ (paintable); - GdkDrawableImplQuartz *drawable_impl = (GdkDrawableImplQuartz *) window_impl; - GdkWindow *window = (GdkWindow *) drawable_impl->wrapper; - GdkWindowObject *private = (GdkWindowObject *) window; - GdkRegion *visible_region; - - visible_region = gdk_drawable_get_visible_region (window); - gdk_region_intersect (visible_region, region); - - if (private->update_area) - { - gdk_region_union (private->update_area, visible_region); - gdk_region_destroy (visible_region); - } - else - { - /* FIXME: When the update_window/update_area handling is abstracted in - * some way, we can remove this check. Currently it might be cleared - * in the generic code without us knowing, see bug #530801. - */ - if (!g_slist_find (update_windows, window)) - update_windows = g_slist_prepend (update_windows, window); - private->update_area = visible_region; - - if (update_idle == 0) - update_idle = gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW, - gdk_window_quartz_update_idle, NULL, NULL); - } -} - -static void -gdk_window_impl_quartz_process_updates (GdkPaintable *paintable, - gboolean update_children) -{ - GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (paintable); - GdkDrawableImplQuartz *drawable_impl = (GdkDrawableImplQuartz *) impl; - GdkWindowObject *private = (GdkWindowObject *) drawable_impl->wrapper; - - if (private->update_area) - { - GDK_QUARTZ_ALLOC_POOL; - gdk_window_quartz_process_updates_internal ((GdkWindow *) private); - update_windows = g_slist_remove (update_windows, private); - GDK_QUARTZ_RELEASE_POOL; - } + NSEnableScreenUpdates (); } static void @@ -523,9 +460,6 @@ gdk_window_impl_quartz_paintable_init (GdkPaintableIface *iface) { iface->begin_paint_region = gdk_window_impl_quartz_begin_paint_region; iface->end_paint = gdk_window_impl_quartz_end_paint; - - iface->invalidate_maybe_recurse = gdk_window_impl_quartz_invalidate_maybe_recurse; - iface->process_updates = gdk_window_impl_quartz_process_updates; } GType @@ -621,7 +555,6 @@ void _gdk_quartz_window_debug_highlight (GdkWindow *window, gint number) { GdkWindowObject *private = GDK_WINDOW_OBJECT (window); - GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl); gint x, y; GdkWindow *toplevel; gint tx, ty; @@ -652,8 +585,8 @@ _gdk_quartz_window_debug_highlight (GdkWindow *window, gint number) y += ty; rect = NSMakeRect (x, - _gdk_quartz_window_get_inverted_screen_y (y + impl->height), - impl->width, impl->height); + _gdk_quartz_window_get_inverted_screen_y (y + private->height), + private->width, private->height); if (debug_window[number] && NSEqualRects (rect, old_rect[number])) return; @@ -721,9 +654,16 @@ _gdk_quartz_window_is_ancestor (GdkWindow *ancestor, gint _gdk_quartz_window_get_inverted_screen_y (gint y) { - NSRect rect = [[NSScreen mainScreen] frame]; + int index; + GdkRectangle gdk_rect; + NSScreen *main_screen = [NSScreen mainScreen]; + NSRect rect = [main_screen frame]; - return rect.size.height - y; + index = [[NSScreen screens] indexOfObject:main_screen]; + + gdk_screen_get_monitor_geometry (_gdk_screen, index, &gdk_rect); + + return gdk_rect.height - y + rect.origin.y + gdk_rect.y; } static GdkWindow * @@ -775,7 +715,7 @@ find_child_window_helper (GdkWindow *window, if (titlebar_height > 0 && x >= temp_x && y >= temp_y - titlebar_height && - x < temp_x + child_impl->width && y < temp_y) + x < temp_x + child_private->width && y < temp_y) { /* The root means "unknown" i.e. a window not managed by * GDK. @@ -785,7 +725,7 @@ find_child_window_helper (GdkWindow *window, } if (x >= temp_x && y >= temp_y && - x < temp_x + child_impl->width && y < temp_y + child_impl->height) + x < temp_x + child_private->width && y < temp_y + child_private->height) { /* Look for child windows. */ return find_child_window_helper (l->data, @@ -807,21 +747,83 @@ _gdk_quartz_window_find_child (GdkWindow *window, gint y) { GdkWindowObject *private = GDK_WINDOW_OBJECT (window); - GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl); - if (x >= 0 && y >= 0 && x < impl->width && y < impl->height) + if (x >= 0 && y >= 0 && x < private->width && y < private->height) return find_child_window_helper (window, x, y, 0, 0); return NULL; } + +static void +generate_motion_event (GdkWindow *window) +{ + NSPoint point; + NSPoint screen_point; + NSWindow *nswindow; + GdkQuartzView *view; + GdkWindowObject *private; + GdkEvent *event; + gint x, y, x_root, y_root; + gdouble xx, yy; + GList *node; + GdkWindow *pointer_window; + + event = gdk_event_new (GDK_MOTION_NOTIFY); + event->any.window = NULL; + event->any.send_event = TRUE; + + private = (GdkWindowObject *)window; + nswindow = ((GdkWindowImplQuartz *)private->impl)->toplevel; + view = (GdkQuartzView *)[nswindow contentView]; + + screen_point = [NSEvent mouseLocation]; + + x_root = screen_point.x; + y_root = _gdk_quartz_window_get_inverted_screen_y (screen_point.y); + + point = [nswindow convertScreenToBase:screen_point]; + + x = point.x; + y = private->height - point.y; + + pointer_window = _gdk_window_find_descendant_at (window, x, y, + &xx, &yy); + + event->any.type = GDK_MOTION_NOTIFY; + event->motion.window = window; + event->motion.time = GDK_CURRENT_TIME; + event->motion.x = x; + event->motion.y = y; + event->motion.x_root = x_root; + event->motion.y_root = y_root; + /* FIXME event->axes */ + event->motion.state = 0; + event->motion.is_hint = FALSE; + event->motion.device = _gdk_display->core_pointer; + + if (event->any.window) + g_object_ref (event->any.window); + + node = _gdk_event_queue_append (gdk_display_get_default (), event); + _gdk_windowing_got_event (gdk_display_get_default (), node, event, 0); +} + void _gdk_quartz_window_did_become_main (GdkWindow *window) { main_window_stack = g_slist_remove (main_window_stack, window); if (GDK_WINDOW_OBJECT (window)->window_type != GDK_WINDOW_TEMP) - main_window_stack = g_slist_prepend (main_window_stack, window); + { + main_window_stack = g_slist_prepend (main_window_stack, window); + + /* We just became the active window, send a motion-notify + * event so things like highlights get set up correctly. + * This motion-notify is sent to the key window. + */ + generate_motion_event (window); + } clear_toplevel_order (); } @@ -857,101 +859,45 @@ _gdk_quartz_window_did_resign_main (GdkWindow *window) clear_toplevel_order (); } -GdkWindow * -_gdk_window_new (GdkWindow *parent, - GdkWindowAttr *attributes, - gint attributes_mask) +void +_gdk_window_impl_new (GdkWindow *window, + GdkWindow *real_parent, + GdkScreen *screen, + GdkVisual *visual, + GdkEventMask event_mask, + GdkWindowAttr *attributes, + gint attributes_mask) { - GdkWindow *window; GdkWindowObject *private; GdkWindowImplQuartz *impl; GdkDrawableImplQuartz *draw_impl; - GdkVisual *visual; GdkWindowImplQuartz *parent_impl; - if (parent && GDK_WINDOW_DESTROYED (parent)) - return NULL; - GDK_QUARTZ_ALLOC_POOL; - if (!parent) - parent = _gdk_root; - - window = g_object_new (GDK_TYPE_WINDOW, NULL); - private = (GdkWindowObject *)window; - private->impl = g_object_new (_gdk_window_impl_get_type (), NULL); - impl = GDK_WINDOW_IMPL_QUARTZ (private->impl); - draw_impl = GDK_DRAWABLE_IMPL_QUARTZ (private->impl); + impl = g_object_new (_gdk_window_impl_get_type (), NULL); + private->impl = (GdkDrawable *)impl; + draw_impl = GDK_DRAWABLE_IMPL_QUARTZ (impl); draw_impl->wrapper = GDK_DRAWABLE (window); - private->parent = (GdkWindowObject *)parent; parent_impl = GDK_WINDOW_IMPL_QUARTZ (private->parent->impl); - private->accept_focus = TRUE; - private->focus_on_map = TRUE; - - if (attributes_mask & GDK_WA_X) - private->x = attributes->x; - else - private->x = 0; - - if (attributes_mask & GDK_WA_Y) - private->y = attributes->y; - else if (attributes_mask & GDK_WA_X) - private->y = 100; - else - private->y = 0; - - private->event_mask = attributes->event_mask; - - impl->width = attributes->width > 1 ? attributes->width : 1; - impl->height = attributes->height > 1 ? attributes->height : 1; - - if (attributes_mask & GDK_WA_VISUAL) - visual = attributes->visual; - else - visual = gdk_screen_get_system_visual (_gdk_screen); - - if (attributes->wclass == GDK_INPUT_ONLY) - { - /* Backwards compatiblity - we've always ignored - * attributes->window_type for input-only windows - * before - */ - if (parent == _gdk_root) - private->window_type = GDK_WINDOW_TEMP; - else - private->window_type = GDK_WINDOW_CHILD; - } - else - private->window_type = attributes->window_type; - - /* Sanity checks */ switch (private->window_type) { case GDK_WINDOW_TOPLEVEL: case GDK_WINDOW_DIALOG: case GDK_WINDOW_TEMP: - if (GDK_WINDOW_TYPE (parent) != GDK_WINDOW_ROOT) + if (GDK_WINDOW_TYPE (private->parent) != GDK_WINDOW_ROOT) { - g_warning (G_STRLOC "Toplevel windows must be created as children of\n" - "of a window of type GDK_WINDOW_ROOT or GDK_WINDOW_FOREIGN"); + /* The common code warns for this case */ + parent_impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (_gdk_root)->impl); } - case GDK_WINDOW_CHILD: - break; - default: - g_warning (G_STRLOC "cannot make windows of type %d", private->window_type); - GDK_QUARTZ_RELEASE_POOL; - return NULL; } - if (attributes->wclass == GDK_INPUT_OUTPUT) + if (!private->input_only) { - private->input_only = FALSE; - private->depth = visual->depth; - if (attributes_mask & GDK_WA_COLORMAP) { draw_impl->colormap = attributes->colormap; @@ -974,22 +920,15 @@ _gdk_window_new (GdkWindow *parent, draw_impl->colormap = gdk_colormap_new (visual, FALSE); } } - - private->bg_color.pixel = 0; - private->bg_color.red = private->bg_color.green = private->bg_color.blue = 0; } else { - private->depth = 0; - private->input_only = TRUE; draw_impl->colormap = gdk_screen_get_system_colormap (_gdk_screen); g_object_ref (draw_impl->colormap); } - private->parent->children = g_list_prepend (private->parent->children, window); - /* Maintain the z-ordered list of children. */ - if (parent != _gdk_root) + if (private->parent != (GdkWindowObject *)_gdk_root) parent_impl->sorted_children = g_list_prepend (parent_impl->sorted_children, window); else clear_toplevel_order (); @@ -1008,13 +947,10 @@ _gdk_window_new (GdkWindow *parent, int style_mask; const char *title; - /* Big hack: We start out outside the screen and move the - * window in before showing it. This makes the initial - * MouseEntered event work if the window ends up right under - * the mouse pointer, bad quartz. - */ - content_rect = NSMakeRect (-500 - impl->width, -500 - impl->height, - impl->width, impl->height); + content_rect = NSMakeRect (private->x, + _gdk_quartz_window_get_inverted_screen_y (private->y) - private->height, + private->width, + private->height); if (attributes->window_type == GDK_WINDOW_TEMP || attributes->type_hint == GDK_WINDOW_TYPE_HINT_SPLASHSCREEN) @@ -1047,6 +983,9 @@ _gdk_window_new (GdkWindow *parent, [impl->toplevel setBackgroundColor:[NSColor clearColor]]; } + content_rect.origin.x = 0; + content_rect.origin.y = 0; + impl->view = [[GdkQuartzView alloc] initWithFrame:content_rect]; [impl->view setGdkWindow:window]; [impl->toplevel setContentView:impl->view]; @@ -1055,11 +994,14 @@ _gdk_window_new (GdkWindow *parent, case GDK_WINDOW_CHILD: { - GdkWindowImplQuartz *parent_impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (parent)->impl); + GdkWindowImplQuartz *parent_impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (private->parent)->impl); - if (attributes->wclass == GDK_INPUT_OUTPUT) + if (!private->input_only) { - NSRect frame_rect = NSMakeRect (private->x, private->y, impl->width, impl->height); + NSRect frame_rect = NSMakeRect (private->x + private->parent->abs_x, + private->y + private->parent->abs_y, + private->width, + private->height); impl->view = [[GdkQuartzView alloc] initWithFrame:frame_rect]; @@ -1080,8 +1022,6 @@ _gdk_window_new (GdkWindow *parent, if (attributes_mask & GDK_WA_TYPE_HINT) gdk_window_set_type_hint (window, attributes->type_hint); - - return window; } void @@ -1090,7 +1030,6 @@ _gdk_windowing_window_init (void) GdkWindowObject *private; GdkWindowImplQuartz *impl; GdkDrawableImplQuartz *drawable_impl; - NSRect rect; g_assert (_gdk_root == NULL); @@ -1098,16 +1037,27 @@ _gdk_windowing_window_init (void) private = (GdkWindowObject *)_gdk_root; private->impl = g_object_new (_gdk_window_impl_get_type (), NULL); + private->impl_window = private; - /* Note: This needs to be reworked for multi-screen support. */ impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (_gdk_root)->impl); - rect = [[NSScreen mainScreen] frame]; - impl->width = rect.size.width; - impl->height = rect.size.height; + + /* The size of the root window should be the same as the size of + * the screen it belongs to. + * + * FIXME: Of course this needs to be updated when you change the monitor + * configuration (add another one, remove one, etc). + */ + private->x = 0; + private->y = 0; + private->abs_x = 0; + private->abs_y = 0; + private->width = gdk_screen_get_width (_gdk_screen); + private->height = gdk_screen_get_height (_gdk_screen); private->state = 0; /* We don't want GDK_WINDOW_STATE_WITHDRAWN here */ private->window_type = GDK_WINDOW_ROOT; private->depth = 24; + private->viewable = TRUE; drawable_impl = GDK_DRAWABLE_IMPL_QUARTZ (private->impl); @@ -1116,20 +1066,18 @@ _gdk_windowing_window_init (void) g_object_ref (drawable_impl->colormap); } -void -_gdk_windowing_window_destroy (GdkWindow *window, - gboolean recursing, - gboolean foreign_destroy) +static void +_gdk_quartz_window_destroy (GdkWindow *window, + gboolean recursing, + gboolean foreign_destroy) { GdkWindowObject *private; GdkWindowImplQuartz *impl; GdkWindowObject *parent; - GdkWindow *mouse_window; private = GDK_WINDOW_OBJECT (window); impl = GDK_WINDOW_IMPL_QUARTZ (private->impl); - update_windows = g_slist_remove (update_windows, window); main_window_stack = g_slist_remove (main_window_stack, window); g_list_free (impl->sorted_children); @@ -1143,22 +1091,8 @@ _gdk_windowing_window_destroy (GdkWindow *window, parent_impl->sorted_children = g_list_remove (parent_impl->sorted_children, window); } - /* If the destroyed window was targeted for a pointer or keyboard - * grab, release the grab. - */ - if (window == _gdk_quartz_pointer_grab_window) - gdk_pointer_ungrab (0); - - if (window == _gdk_quartz_keyboard_grab_window) - gdk_keyboard_ungrab (0); - _gdk_quartz_drawable_finish (GDK_DRAWABLE (impl)); - mouse_window = _gdk_quartz_events_get_mouse_window (FALSE); - if (window == mouse_window || - _gdk_quartz_window_is_ancestor (window, mouse_window)) - _gdk_quartz_events_update_mouse_window (_gdk_root); - if (!recursing && !foreign_destroy) { GDK_QUARTZ_ALLOC_POOL; @@ -1178,39 +1112,18 @@ _gdk_windowing_window_destroy_foreign (GdkWindow *window) /* Foreign windows aren't supported in OSX. */ } -static gboolean -all_parents_shown (GdkWindowObject *private) -{ - while (GDK_WINDOW_IS_MAPPED (private)) - { - if (private->parent) - private = (GdkWindowObject *)private->parent; - else - return TRUE; - } - - return FALSE; -} - -/* Note: the raise argument is not really used, it doesn't seem - * possible to show a window without raising it? - */ +/* FIXME: This might be possible to simplify with client-side windows. Also + * note that already_mapped is not used yet, see the x11 backend. +*/ static void -gdk_window_quartz_show (GdkWindow *window, - gboolean raise) +gdk_window_quartz_show (GdkWindow *window, gboolean already_mapped) { - GdkWindowObject *private; - GdkWindowImplQuartz *impl; + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl); gboolean focus_on_map; - if (GDK_WINDOW_DESTROYED (window)) - return; - GDK_QUARTZ_ALLOC_POOL; - private = (GdkWindowObject *)window; - impl = GDK_WINDOW_IMPL_QUARTZ (private->impl); - if (!GDK_WINDOW_IS_MAPPED (window)) focus_on_map = private->focus_on_map; else @@ -1220,14 +1133,13 @@ gdk_window_quartz_show (GdkWindow *window, { gboolean make_key; - /* Move the window into place, to guarantee that we get the - * initial MouseEntered event. - */ - make_key = (private->accept_focus && focus_on_map && raise && + make_key = (private->accept_focus && focus_on_map && private->window_type != GDK_WINDOW_TEMP); [(GdkQuartzWindow*)impl->toplevel showAndMakeKey:make_key]; clear_toplevel_order (); + + _gdk_quartz_events_send_map_event (window); } else { @@ -1236,9 +1148,6 @@ gdk_window_quartz_show (GdkWindow *window, [impl->view setNeedsDisplay:YES]; - if (all_parents_shown (private->parent)) - _gdk_quartz_events_send_map_events (window); - gdk_synthesize_window_state (window, GDK_WINDOW_STATE_WITHDRAWN, 0); if (private->state & GDK_WINDOW_STATE_MAXIMIZED) @@ -1250,12 +1159,6 @@ gdk_window_quartz_show (GdkWindow *window, if (impl->transient_for && !GDK_WINDOW_DESTROYED (impl->transient_for)) _gdk_quartz_window_attach_to_parent (window); - /* Create a crossing event for windows that pop up under the mouse. Part - * of the workarounds for problems with the tracking rect API. - */ - if (impl->toplevel) - _gdk_quartz_events_trigger_crossing_events (TRUE); - GDK_QUARTZ_RELEASE_POOL; } @@ -1310,24 +1213,12 @@ gdk_window_quartz_hide (GdkWindow *window) { GdkWindowObject *private = (GdkWindowObject *)window; GdkWindowImplQuartz *impl; - GdkWindow *mouse_window; /* Make sure we're not stuck in fullscreen mode. */ if (get_fullscreen_geometry (window)) SetSystemUIMode (kUIModeNormal, 0); - if (GDK_WINDOW_DESTROYED (window)) - return; - - mouse_window = _gdk_quartz_events_get_mouse_window (FALSE); - if (window == mouse_window || - _gdk_quartz_window_is_ancestor (window, mouse_window)) - _gdk_quartz_events_update_mouse_window (_gdk_root); - - if (GDK_WINDOW_IS_MAPPED (window)) - gdk_synthesize_window_state (window, - 0, - GDK_WINDOW_STATE_WITHDRAWN); + check_grab_unmap (window); _gdk_window_clear_update_area (window); @@ -1349,12 +1240,6 @@ gdk_window_quartz_hide (GdkWindow *window) { [impl->view setHidden:YES]; } - - if (window == _gdk_quartz_pointer_grab_window) - gdk_pointer_ungrab (0); - - if (window == _gdk_quartz_keyboard_grab_window) - gdk_keyboard_ungrab (0); } void @@ -1386,8 +1271,8 @@ move_resize_window_internal (GdkWindow *window, if ((x == -1 || (x == private->x)) && (y == -1 || (y == private->y)) && - (width == -1 || (width == impl->width)) && - (height == -1 || (height == impl->height))) + (width == -1 || (width == private->width)) && + (height == -1 || (height == private->height))) { return; } @@ -1426,10 +1311,10 @@ move_resize_window_internal (GdkWindow *window, } if (width != -1) - impl->width = width; + private->width = width; if (height != -1) - impl->height = height; + private->height = height; GDK_QUARTZ_ALLOC_POOL; @@ -1438,19 +1323,12 @@ move_resize_window_internal (GdkWindow *window, NSRect content_rect; NSRect frame_rect; - /* We don't update the NSWindow while unmapped, since we move windows - * off-screen when hiding in order for MouseEntered to be triggered - * reliably when showing windows and they appear under the mouse. - */ - if (GDK_WINDOW_IS_MAPPED (window)) - { - content_rect = NSMakeRect (private->x, - _gdk_quartz_window_get_inverted_screen_y (private->y + impl->height), - impl->width, impl->height); + content_rect = NSMakeRect (private->x, + _gdk_quartz_window_get_inverted_screen_y (private->y + private->height), + private->width, private->height); - frame_rect = [impl->toplevel frameRectForContentRect:content_rect]; - [impl->toplevel setFrame:frame_rect display:YES]; - } + frame_rect = [impl->toplevel frameRectForContentRect:content_rect]; + [impl->toplevel setFrame:frame_rect display:YES]; } else { @@ -1458,7 +1336,7 @@ move_resize_window_internal (GdkWindow *window, { NSRect nsrect; - nsrect = NSMakeRect (private->x, private->y, impl->width, impl->height); + nsrect = NSMakeRect (private->x, private->y, private->width, private->height); /* The newly visible area of this window in a coordinate * system rooted at the origin of this window. @@ -1500,12 +1378,7 @@ move_resize_window_internal (GdkWindow *window, gdk_region_get_rectangles (expose_region, &rects, &n_rects); for (n = 0; n < n_rects; ++n) - { - [impl->view setNeedsDisplayInRect:NSMakeRect (rects[n].x, - rects[n].y, - rects[n].width, - rects[n].height)]; - } + _gdk_quartz_window_set_needs_display_in_rect (window, &rects[n]); g_free (rects); } @@ -1588,6 +1461,9 @@ gdk_window_quartz_move_resize (GdkWindow *window, } } +/* FIXME: This might need fixing (reparenting didn't work before client-side + * windows either). + */ static gboolean gdk_window_quartz_reparent (GdkWindow *window, GdkWindow *new_parent, @@ -1598,7 +1474,7 @@ gdk_window_quartz_reparent (GdkWindow *window, GdkWindowImplQuartz *impl, *old_parent_impl, *new_parent_impl; NSView *view, *new_parent_view; - if (!new_parent || new_parent == _gdk_root) + if (new_parent == _gdk_root) { /* Could be added, just needs implementing. */ g_warning ("Reparenting to root window is not supported yet in the Mac OS X backend"); @@ -1623,31 +1499,16 @@ gdk_window_quartz_reparent (GdkWindow *window, [view release]; - private->x = x; - private->y = y; - private->parent = (GdkWindowObject *)new_parent; + private->parent = new_parent_private; if (old_parent_private) { - old_parent_private->children = g_list_remove (old_parent_private->children, window); old_parent_impl->sorted_children = g_list_remove (old_parent_impl->sorted_children, window); } - new_parent_private->children = g_list_prepend (new_parent_private->children, window); new_parent_impl->sorted_children = g_list_prepend (new_parent_impl->sorted_children, window); - return TRUE; -} - -static void -gdk_window_quartz_clear_area (GdkWindow *window, - gint x, - gint y, - gint width, - gint height, - gboolean send_expose) -{ - /* FIXME: Implement */ + return FALSE; } /* Get the toplevel ordering from NSApp and update our own list. We do @@ -1763,91 +1624,50 @@ gdk_window_quartz_lower (GdkWindow *window) } } +static void +gdk_window_quartz_restack_toplevel (GdkWindow *window, + GdkWindow *sibling, + gboolean above) +{ + /* FIXME: Implement this */ +} + static void gdk_window_quartz_set_background (GdkWindow *window, const GdkColor *color) { - GdkWindowObject *private = (GdkWindowObject *)window; - GdkWindowImplQuartz *impl; - - if (GDK_WINDOW_DESTROYED (window)) - return; - - impl = GDK_WINDOW_IMPL_QUARTZ (private->impl); - - private->bg_color = *color; - - if (private->bg_pixmap && - private->bg_pixmap != GDK_PARENT_RELATIVE_BG && - private->bg_pixmap != GDK_NO_BG) - g_object_unref (private->bg_pixmap); - - private->bg_pixmap = NULL; + /* FIXME: We could theoretically set the background color for toplevels + * here. (Currently we draw the background before emitting expose events) + */ } static void gdk_window_quartz_set_back_pixmap (GdkWindow *window, - GdkPixmap *pixmap, - gboolean parent_relative) + GdkPixmap *pixmap) { - GdkWindowObject *private = (GdkWindowObject *)window; - - if (GDK_WINDOW_DESTROYED (window)) - return; - - if (private->bg_pixmap && - private->bg_pixmap != GDK_PARENT_RELATIVE_BG && - private->bg_pixmap != GDK_NO_BG) - g_object_unref (private->bg_pixmap); - - if (parent_relative) - { - private->bg_pixmap = GDK_PARENT_RELATIVE_BG; - GDK_NOTE (MISC, g_print (G_STRLOC ": setting background pixmap to parent_relative\n")); - } - else - { - if (pixmap) - { - g_object_ref (pixmap); - private->bg_pixmap = pixmap; - } - else - { - private->bg_pixmap = GDK_NO_BG; - } - } + /* FIXME: Could theoretically set some background image here. (Currently + * the back pixmap is drawn before emitting expose events. + */ } static void gdk_window_quartz_set_cursor (GdkWindow *window, GdkCursor *cursor) { - GdkWindowImplQuartz *impl; GdkCursorPrivate *cursor_private; NSCursor *nscursor; - impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl); cursor_private = (GdkCursorPrivate *)cursor; if (GDK_WINDOW_DESTROYED (window)) return; - GDK_QUARTZ_ALLOC_POOL; - if (!cursor) - nscursor = NULL; + nscursor = [NSCursor arrowCursor]; else - nscursor = [cursor_private->nscursor retain]; + nscursor = cursor_private->nscursor; - if (impl->nscursor) - [impl->nscursor release]; - - impl->nscursor = nscursor; - - GDK_QUARTZ_RELEASE_POOL; - - _gdk_quartz_events_update_cursor (_gdk_quartz_events_get_mouse_window (TRUE)); + [nscursor set]; } static void @@ -1859,12 +1679,14 @@ gdk_window_quartz_get_geometry (GdkWindow *window, gint *depth) { GdkWindowImplQuartz *impl; + GdkWindowObject *private; NSRect ns_rect; if (GDK_WINDOW_DESTROYED (window)) return; impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl); + private = GDK_WINDOW_OBJECT (window); if (window == _gdk_root) { if (x) @@ -1873,9 +1695,9 @@ gdk_window_quartz_get_geometry (GdkWindow *window, *y = 0; if (width) - *width = impl->width; + *width = private->width; if (height) - *height = impl->height; + *height = private->height; } else if (WINDOW_IS_TOPLEVEL (window)) { @@ -1928,9 +1750,11 @@ gdk_window_quartz_get_geometry (GdkWindow *window, } static gint -gdk_window_quartz_get_origin (GdkWindow *window, - gint *x, - gint *y) +gdk_window_quartz_get_root_coords (GdkWindow *window, + gint x, + gint y, + gint *root_x, + gint *root_y) { GdkWindowObject *private; int tmp_x = 0, tmp_y = 0; @@ -1940,18 +1764,21 @@ gdk_window_quartz_get_origin (GdkWindow *window, if (GDK_WINDOW_DESTROYED (window)) { - if (x) - *x = 0; - if (y) - *y = 0; + if (root_x) + *root_x = 0; + if (root_y) + *root_y = 0; return 0; } if (window == _gdk_root) { - *x = 0; - *y = 0; + if (root_x) + *root_x = x; + if (root_y) + *root_y = y; + return 1; } @@ -1962,32 +1789,33 @@ gdk_window_quartz_get_origin (GdkWindow *window, content_rect = [impl->toplevel contentRectForFrameRect:[impl->toplevel frame]]; - tmp_x = content_rect.origin.x; - tmp_y = _gdk_quartz_window_get_inverted_screen_y (content_rect.origin.y + content_rect.size.height); + tmp_x = x + content_rect.origin.x; + tmp_y = y + _gdk_quartz_window_get_inverted_screen_y (content_rect.origin.y + content_rect.size.height); while (private != GDK_WINDOW_OBJECT (toplevel)) { - tmp_x += private->x; - tmp_y += private->y; + if (_gdk_window_has_impl ((GdkWindow *)private)) + { + tmp_x += private->x; + tmp_y += private->y; + } private = private->parent; } - if (x) - *x = tmp_x; - if (y) - *y = tmp_y; + if (root_x) + *root_x = tmp_x; + if (root_y) + *root_y = tmp_y; return TRUE; } -gboolean -gdk_window_get_deskrelative_origin (GdkWindow *window, - gint *x, - gint *y) +static gboolean +gdk_window_quartz_get_deskrelative_origin (GdkWindow *window, + gint *x, + gint *y) { - g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE); - return gdk_window_get_origin (window, x, y); } @@ -1998,8 +1826,6 @@ gdk_window_get_root_origin (GdkWindow *window, { GdkRectangle rect; - g_return_if_fail (GDK_IS_WINDOW (window)); - rect.x = 0; rect.y = 0; @@ -2012,27 +1838,12 @@ gdk_window_get_root_origin (GdkWindow *window, *y = rect.y; } -/* Returns coordinates relative to the root. */ -void -_gdk_windowing_get_pointer (GdkDisplay *display, - GdkScreen **screen, - gint *x, - gint *y, - GdkModifierType *mask) -{ - g_return_if_fail (display == _gdk_display); - - *screen = _gdk_screen; - _gdk_windowing_window_get_pointer (_gdk_display, _gdk_root, x, y, mask); -} - /* Returns coordinates relative to the passed in window. */ -GdkWindow * -_gdk_windowing_window_get_pointer (GdkDisplay *display, - GdkWindow *window, - gint *x, - gint *y, - GdkModifierType *mask) +static GdkWindow * +gdk_window_quartz_get_pointer_helper (GdkWindow *window, + gint *x, + gint *y, + GdkModifierType *mask) { GdkWindowObject *toplevel; GdkWindowObject *private; @@ -2040,6 +1851,8 @@ _gdk_windowing_window_get_pointer (GdkDisplay *display, gint x_tmp, y_tmp; GdkWindow *found_window; + g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL); + if (GDK_WINDOW_DESTROYED (window)) { *x = 0; @@ -2065,23 +1878,15 @@ _gdk_windowing_window_get_pointer (GdkDisplay *display, NSWindow *nswindow; impl = GDK_WINDOW_IMPL_QUARTZ (toplevel->impl); + private = GDK_WINDOW_OBJECT (toplevel); nswindow = impl->toplevel; point = [nswindow mouseLocationOutsideOfEventStream]; + x_tmp = point.x; - y_tmp = impl->height - point.y; - } + y_tmp = private->height - point.y; - /* The coords are relative to the toplevel of the passed in window - * at this point, make them relative to the passed in window: - */ - private = GDK_WINDOW_OBJECT (window); - while (private != toplevel) - { - x_tmp -= private->x; - y_tmp -= private->y; - - private = private->parent; + window = (GdkWindow *)toplevel; } found_window = _gdk_quartz_window_find_child (window, x_tmp, y_tmp); @@ -2096,6 +1901,29 @@ _gdk_windowing_window_get_pointer (GdkDisplay *display, return found_window; } +static gboolean +gdk_window_quartz_get_pointer (GdkWindow *window, + gint *x, + gint *y, + GdkModifierType *mask) +{ + return gdk_window_quartz_get_pointer_helper (window, x, y, mask) != NULL; +} + +/* Returns coordinates relative to the root. */ +void +_gdk_windowing_get_pointer (GdkDisplay *display, + GdkScreen **screen, + gint *x, + gint *y, + GdkModifierType *mask) +{ + g_return_if_fail (display == _gdk_display); + + *screen = _gdk_screen; + gdk_window_quartz_get_pointer_helper (_gdk_root, x, y, mask); +} + void gdk_display_warp_pointer (GdkDisplay *display, GdkScreen *screen, @@ -2107,18 +1935,19 @@ gdk_display_warp_pointer (GdkDisplay *display, /* Returns coordinates relative to the found window. */ GdkWindow * -_gdk_windowing_window_at_pointer (GdkDisplay *display, - gint *win_x, - gint *win_y) +_gdk_windowing_window_at_pointer (GdkDisplay *display, + gint *win_x, + gint *win_y, + GdkModifierType *mask, + gboolean get_toplevel) { - GdkModifierType mask; GdkWindow *found_window; gint x, y; + GdkModifierType tmp_mask = 0; - found_window = _gdk_windowing_window_get_pointer (display, - _gdk_root, - &x, &y, - &mask); + found_window = gdk_window_quartz_get_pointer_helper (_gdk_root, + &x, &y, + &tmp_mask); if (found_window) { GdkWindowObject *private; @@ -2145,6 +1974,29 @@ _gdk_windowing_window_at_pointer (GdkDisplay *display, *win_y = -1; } + if (mask) + *mask = tmp_mask; + + if (get_toplevel) + { + GdkWindowObject *w = (GdkWindowObject *)found_window; + /* Requested toplevel, find it. */ + /* TODO: This can be implemented more efficient by never + recursing into children in the first place */ + if (w) + { + /* Convert to toplevel */ + while (w->parent != NULL && + w->parent->window_type != GDK_WINDOW_ROOT) + { + *win_x += w->x; + *win_y += w->y; + w = w->parent; + } + found_window = (GdkWindow *)w; + } + } + return found_window; } @@ -2161,16 +2013,17 @@ static void gdk_window_quartz_set_events (GdkWindow *window, GdkEventMask event_mask) { - if (!GDK_WINDOW_DESTROYED (window)) - { - GDK_WINDOW_OBJECT (window)->event_mask = event_mask; - } + /* The mask is set in the common code. */ } void gdk_window_set_urgency_hint (GdkWindow *window, gboolean urgent) { + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL (window)) + return; + /* FIXME: Implement */ } @@ -2181,10 +2034,10 @@ gdk_window_set_geometry_hints (GdkWindow *window, { GdkWindowImplQuartz *impl; - g_return_if_fail (GDK_IS_WINDOW (window)); g_return_if_fail (geometry != NULL); - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL (window)) return; impl = GDK_WINDOW_IMPL_QUARTZ (((GdkWindowObject *) window)->impl); @@ -2258,10 +2111,10 @@ gdk_window_set_title (GdkWindow *window, { GdkWindowImplQuartz *impl; - g_return_if_fail (GDK_IS_WINDOW (window)); g_return_if_fail (title != NULL); - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL (window)) return; impl = GDK_WINDOW_IMPL_QUARTZ (((GdkWindowObject *)window)->impl); @@ -2278,6 +2131,10 @@ void gdk_window_set_role (GdkWindow *window, const gchar *role) { + if (GDK_WINDOW_DESTROYED (window) || + WINDOW_IS_TOPLEVEL (window)) + return; + /* FIXME: Implement */ } @@ -2288,7 +2145,8 @@ gdk_window_set_transient_for (GdkWindow *window, GdkWindowImplQuartz *window_impl; GdkWindowImplQuartz *parent_impl; - if (GDK_WINDOW_DESTROYED (window) || GDK_WINDOW_DESTROYED (parent)) + if (GDK_WINDOW_DESTROYED (window) || GDK_WINDOW_DESTROYED (parent) || + !WINDOW_IS_TOPLEVEL (window)) return; window_impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl); @@ -2343,38 +2201,14 @@ gdk_window_quartz_shape_combine_region (GdkWindow *window, } static void -gdk_window_quartz_shape_combine_mask (GdkWindow *window, - GdkBitmap *mask, - gint x, - gint y) +gdk_window_quartz_input_shape_combine_region (GdkWindow *window, + const GdkRegion *shape_region, + gint offset_x, + gint offset_y) { /* FIXME: Implement */ } -void -gdk_window_input_shape_combine_mask (GdkWindow *window, - GdkBitmap *mask, - gint x, - gint y) -{ - /* FIXME: Implement */ -} - -void -gdk_window_input_shape_combine_region (GdkWindow *window, - const GdkRegion *shape_region, - gint offset_x, - gint offset_y) -{ - /* FIXME: Implement */ -} - -void -gdk_window_set_child_input_shapes (GdkWindow *window) -{ - /* FIXME: IMplement */ -} - void gdk_window_set_override_redirect (GdkWindow *window, gboolean override_redirect) @@ -2388,35 +2222,19 @@ gdk_window_set_accept_focus (GdkWindow *window, { GdkWindowObject *private; - g_return_if_fail (GDK_IS_WINDOW (window)); - private = (GdkWindowObject *)window; private->accept_focus = accept_focus != FALSE; } -static void -gdk_window_quartz_set_child_shapes (GdkWindow *window) -{ - /* FIXME: Implement */ -} - -static void -gdk_window_quartz_merge_child_shapes (GdkWindow *window) -{ - /* FIXME: Implement */ -} - -void -gdk_window_merge_child_input_shapes (GdkWindow *window) -{ - /* FIXME: Implement */ -} - static gboolean gdk_window_quartz_set_static_gravities (GdkWindow *window, gboolean use_static) { + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL (window)) + return FALSE; + /* FIXME: Implement */ return FALSE; } @@ -2427,8 +2245,6 @@ gdk_window_set_focus_on_map (GdkWindow *window, { GdkWindowObject *private; - g_return_if_fail (GDK_IS_WINDOW (window)); - private = (GdkWindowObject *)window; private->focus_on_map = focus_on_map != FALSE; @@ -2440,8 +2256,6 @@ gdk_window_set_icon (GdkWindow *window, GdkPixmap *pixmap, GdkBitmap *mask) { - g_return_if_fail (GDK_IS_WINDOW (window)); - /* FIXME: Implement */ } @@ -2449,8 +2263,6 @@ void gdk_window_set_icon_name (GdkWindow *window, const gchar *name) { - g_return_if_fail (GDK_IS_WINDOW (window)); - /* FIXME: Implement */ } @@ -2461,20 +2273,19 @@ gdk_window_focus (GdkWindow *window, GdkWindowObject *private; GdkWindowImplQuartz *impl; - g_return_if_fail (GDK_IS_WINDOW (window)); - private = (GdkWindowObject*) window; impl = GDK_WINDOW_IMPL_QUARTZ (private->impl); - if (impl->toplevel) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL (window)) + return; + + if (private->accept_focus && private->window_type != GDK_WINDOW_TEMP) { - if (private->accept_focus && private->window_type != GDK_WINDOW_TEMP) - { - GDK_QUARTZ_ALLOC_POOL; - [impl->toplevel makeKeyAndOrderFront:impl->toplevel]; - clear_toplevel_order (); - GDK_QUARTZ_RELEASE_POOL; - } + GDK_QUARTZ_ALLOC_POOL; + [impl->toplevel makeKeyAndOrderFront:impl->toplevel]; + clear_toplevel_order (); + GDK_QUARTZ_RELEASE_POOL; } } @@ -2564,9 +2375,8 @@ gdk_window_set_type_hint (GdkWindow *window, { GdkWindowImplQuartz *impl; - g_return_if_fail (GDK_IS_WINDOW (window)); - - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL (window)) return; impl = GDK_WINDOW_IMPL_QUARTZ (((GdkWindowObject *) window)->impl); @@ -2584,7 +2394,8 @@ gdk_window_set_type_hint (GdkWindow *window, GdkWindowTypeHint gdk_window_get_type_hint (GdkWindow *window) { - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL (window)) return GDK_WINDOW_TYPE_HINT_NORMAL; return GDK_WINDOW_IMPL_QUARTZ (((GdkWindowObject *) window)->impl)->type_hint; @@ -2594,7 +2405,9 @@ void gdk_window_set_modal_hint (GdkWindow *window, gboolean modal) { - g_return_if_fail (GDK_IS_WINDOW (window)); + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL (window)) + return; /* FIXME: Implement */ } @@ -2603,7 +2416,9 @@ void gdk_window_set_skip_taskbar_hint (GdkWindow *window, gboolean skips_taskbar) { - g_return_if_fail (GDK_IS_WINDOW (window)); + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL (window)) + return; /* FIXME: Implement */ } @@ -2612,7 +2427,9 @@ void gdk_window_set_skip_pager_hint (GdkWindow *window, gboolean skips_pager) { - g_return_if_fail (GDK_IS_WINDOW (window)); + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL (window)) + return; /* FIXME: Implement */ } @@ -2661,9 +2478,8 @@ gdk_window_begin_move_drag (GdkWindow *window, GdkWindowObject *private; GdkWindowImplQuartz *impl; - g_return_if_fail (GDK_IS_WINDOW (window)); - - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL (window)) return; private = GDK_WINDOW_OBJECT (window); @@ -2694,7 +2510,6 @@ gdk_window_get_frame_extents (GdkWindow *window, GdkWindowImplQuartz *impl; NSRect ns_rect; - g_return_if_fail (GDK_IS_WINDOW (window)); g_return_if_fail (rect != NULL); private = GDK_WINDOW_OBJECT (window); @@ -2704,9 +2519,6 @@ gdk_window_get_frame_extents (GdkWindow *window, rect->width = 1; rect->height = 1; - if (GDK_WINDOW_DESTROYED (window)) - return; - toplevel = gdk_window_get_toplevel (window); impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (toplevel)->impl); @@ -2726,10 +2538,8 @@ gdk_window_set_decorations (GdkWindow *window, int old_mask, new_mask; NSView *old_view; - g_return_if_fail (GDK_IS_WINDOW (window)); - g_return_if_fail (WINDOW_IS_TOPLEVEL (window)); - - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL (window)) return; impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl); @@ -2804,10 +2614,8 @@ gdk_window_get_decorations (GdkWindow *window, { GdkWindowImplQuartz *impl; - g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE); - g_return_val_if_fail (WINDOW_IS_TOPLEVEL (window), FALSE); - - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL (window)) return FALSE; impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl); @@ -2838,14 +2646,6 @@ gdk_window_set_functions (GdkWindow *window, /* FIXME: Implement */ } -static void -gdk_window_quartz_get_offsets (GdkWindow *window, - gint *x_offset, - gint *y_offset) -{ - *x_offset = *y_offset = 0; -} - gboolean _gdk_windowing_window_queue_antiexpose (GdkWindow *window, GdkRegion *area) @@ -2856,13 +2656,17 @@ _gdk_windowing_window_queue_antiexpose (GdkWindow *window, void gdk_window_stick (GdkWindow *window) { - g_return_if_fail (GDK_IS_WINDOW (window)); + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL (window)) + return; } void gdk_window_unstick (GdkWindow *window) { - g_return_if_fail (GDK_IS_WINDOW (window)); + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL (window)) + return; } void @@ -2870,9 +2674,8 @@ gdk_window_maximize (GdkWindow *window) { GdkWindowImplQuartz *impl; - g_return_if_fail (GDK_IS_WINDOW (window)); - - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL (window)) return; impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl); @@ -2899,9 +2702,8 @@ gdk_window_unmaximize (GdkWindow *window) { GdkWindowImplQuartz *impl; - g_return_if_fail (GDK_IS_WINDOW (window)); - - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL (window)) return; impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl); @@ -2928,11 +2730,10 @@ gdk_window_iconify (GdkWindow *window) { GdkWindowImplQuartz *impl; - g_return_if_fail (GDK_IS_WINDOW (window)); - - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL (window)) return; - + impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl); if (GDK_WINDOW_IS_MAPPED (window)) @@ -2957,9 +2758,8 @@ gdk_window_deiconify (GdkWindow *window) { GdkWindowImplQuartz *impl; - g_return_if_fail (GDK_IS_WINDOW (window)); - - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL (window)) return; impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl); @@ -2992,11 +2792,11 @@ gdk_window_fullscreen (GdkWindow *window) { FullscreenSavedGeometry *geometry; GdkWindowObject *private = (GdkWindowObject *) window; - GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl); NSRect frame; - g_return_if_fail (GDK_IS_WINDOW (window)); - g_return_if_fail (WINDOW_IS_TOPLEVEL (window)); + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL (window)) + return; geometry = get_fullscreen_geometry (window); if (!geometry) @@ -3005,8 +2805,8 @@ gdk_window_fullscreen (GdkWindow *window) geometry->x = private->x; geometry->y = private->y; - geometry->width = impl->width; - geometry->height = impl->height; + geometry->width = private->width; + geometry->height = private->height; if (!gdk_window_get_decorations (window, &geometry->decor)) geometry->decor = GDK_DECOR_ALL; @@ -3033,8 +2833,9 @@ gdk_window_unfullscreen (GdkWindow *window) { FullscreenSavedGeometry *geometry; - g_return_if_fail (GDK_IS_WINDOW (window)); - g_return_if_fail (WINDOW_IS_TOPLEVEL (window)); + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL (window)) + return; geometry = get_fullscreen_geometry (window); if (geometry) @@ -3063,9 +2864,9 @@ gdk_window_set_keep_above (GdkWindow *window, gboolean setting) gint level; g_return_if_fail (GDK_IS_WINDOW (window)); - g_return_if_fail (WINDOW_IS_TOPLEVEL (window)); - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL (window)) return; level = window_type_hint_to_level (gdk_window_get_type_hint (window)); @@ -3082,9 +2883,9 @@ gdk_window_set_keep_below (GdkWindow *window, gboolean setting) gint level; g_return_if_fail (GDK_IS_WINDOW (window)); - g_return_if_fail (WINDOW_IS_TOPLEVEL (window)); - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL (window)) return; level = window_type_hint_to_level (gdk_window_get_type_hint (window)); @@ -3096,9 +2897,12 @@ gdk_window_set_keep_below (GdkWindow *window, gboolean setting) GdkWindow * gdk_window_get_group (GdkWindow *window) { - g_return_val_if_fail (GDK_IS_WINDOW (window), NULL); g_return_val_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD, NULL); + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL (window)) + return NULL; + /* FIXME: Implement */ return NULL; @@ -3146,11 +2950,14 @@ gdk_window_configure_finished (GdkWindow *window) void gdk_window_destroy_notify (GdkWindow *window) { + check_grab_destroy (window); } void -gdk_window_beep (GdkWindow *window) +_gdk_windowing_window_beep (GdkWindow *window) { + g_return_if_fail (GDK_IS_WINDOW (window)); + gdk_display_beep (_gdk_display); } @@ -3164,7 +2971,8 @@ gdk_window_set_opacity (GdkWindow *window, g_return_if_fail (GDK_IS_WINDOW (window)); g_return_if_fail (WINDOW_IS_TOPLEVEL (window)); - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL (window)) return; if (opacity < 0) @@ -3180,6 +2988,27 @@ _gdk_windowing_window_set_composited (GdkWindow *window, gboolean composited) { } +GdkRegion * +_gdk_windowing_get_shape_for_mask (GdkBitmap *mask) +{ + /* FIXME: implement */ + return NULL; +} + +GdkRegion * +_gdk_windowing_window_get_shape (GdkWindow *window) +{ + /* FIXME: implement */ + return NULL; +} + +GdkRegion * +_gdk_windowing_window_get_input_shape (GdkWindow *window) +{ + /* FIXME: implement */ + return NULL; +} + static void gdk_window_impl_iface_init (GdkWindowImplIface *iface) { @@ -3188,22 +3017,22 @@ gdk_window_impl_iface_init (GdkWindowImplIface *iface) iface->withdraw = gdk_window_quartz_withdraw; iface->set_events = gdk_window_quartz_set_events; iface->get_events = gdk_window_quartz_get_events; - iface->clear_area = gdk_window_quartz_clear_area; iface->raise = gdk_window_quartz_raise; iface->lower = gdk_window_quartz_lower; + iface->restack_toplevel = gdk_window_quartz_restack_toplevel; iface->move_resize = gdk_window_quartz_move_resize; - iface->scroll = _gdk_quartz_window_scroll; - iface->move_region = _gdk_quartz_window_move_region; iface->set_background = gdk_window_quartz_set_background; iface->set_back_pixmap = gdk_window_quartz_set_back_pixmap; iface->reparent = gdk_window_quartz_reparent; iface->set_cursor = gdk_window_quartz_set_cursor; iface->get_geometry = gdk_window_quartz_get_geometry; - iface->get_origin = gdk_window_quartz_get_origin; - iface->shape_combine_mask = gdk_window_quartz_shape_combine_mask; + iface->get_root_coords = gdk_window_quartz_get_root_coords; + iface->get_pointer = gdk_window_quartz_get_pointer; + iface->get_deskrelative_origin = gdk_window_quartz_get_deskrelative_origin; iface->shape_combine_region = gdk_window_quartz_shape_combine_region; - iface->set_child_shapes = gdk_window_quartz_set_child_shapes; - iface->merge_child_shapes = gdk_window_quartz_merge_child_shapes; + iface->input_shape_combine_region = gdk_window_quartz_input_shape_combine_region; iface->set_static_gravities = gdk_window_quartz_set_static_gravities; - iface->get_offsets = gdk_window_quartz_get_offsets; + iface->queue_antiexpose = _gdk_quartz_window_queue_antiexpose; + iface->queue_translation = _gdk_quartz_window_queue_translation; + iface->destroy = _gdk_quartz_window_destroy; } diff --git a/gdk/quartz/gdkwindow-quartz.h b/gdk/quartz/gdkwindow-quartz.h index b3e3fb9db2..8d47512344 100644 --- a/gdk/quartz/gdkwindow-quartz.h +++ b/gdk/quartz/gdkwindow-quartz.h @@ -45,17 +45,12 @@ struct _GdkWindowImplQuartz { GdkDrawableImplQuartz parent_instance; - gint width; - gint height; - NSWindow *toplevel; NSTrackingRectTag tracking_rect; GdkQuartzView *view; GdkWindowTypeHint type_hint; - NSCursor *nscursor; - GdkRegion *paint_clip_region; gint begin_paint_count; gint in_paint_rect_count; @@ -64,6 +59,8 @@ struct _GdkWindowImplQuartz /* Sorted by z-order */ GList *sorted_children; + + GdkRegion *needs_display_region; }; struct _GdkWindowImplQuartzClass diff --git a/gdk/testgdk.c b/gdk/testgdk.c index 6a38b54d16..c7ca87bba8 100644 --- a/gdk/testgdk.c +++ b/gdk/testgdk.c @@ -340,7 +340,7 @@ test_gcs (void) pixmap = gdk_pixmap_new (NULL, 1, 1, 1); black_bitmap_gc = gdk_gc_new (pixmap); - gdk_pixmap_unref (pixmap); + g_object_unref (pixmap); } /* Create pixmaps, check that properties are as expected. @@ -370,7 +370,7 @@ test_pixmaps (gint depth) QTEST (image->height == height); QTEST (image->depth == depth); gdk_image_destroy (image); - gdk_pixmap_unref (pixmap); + g_object_unref (pixmap); } TEST (retval); } @@ -569,7 +569,7 @@ test_points (void) gdk_gc_set_function (gcs[j], GDK_COPY); } - gdk_pixmap_unref (pixmap); + g_object_unref (pixmap); pixmap = gdk_pixmap_new (w, width, height, 1); test_one_point_on_drawable (pixmap, black_bitmap_gc, 1); @@ -579,7 +579,7 @@ test_points (void) test_one_point_on_drawable (pixmap, black_bitmap_gc, 1); } - gdk_pixmap_unref (pixmap); + g_object_unref (pixmap); } static void @@ -684,7 +684,7 @@ test_lines (void) gdk_gc_set_function (gcs[j], GDK_COPY); } - gdk_pixmap_unref (pixmap); + g_object_unref (pixmap); } static void @@ -789,7 +789,7 @@ test_rectangles (void) gdk_gc_set_function (gcs[j], GDK_COPY); } - gdk_pixmap_unref (pixmap); + g_object_unref (pixmap); } static void @@ -880,7 +880,7 @@ test_arcs (void) gdk_gc_set_function (gcs[j], GDK_COPY); } - gdk_pixmap_unref (pixmap); + g_object_unref (pixmap); } /* Test region operations. diff --git a/gdk/win32/gdkdisplay-win32.c b/gdk/win32/gdkdisplay-win32.c index 75fde08659..340d243f33 100644 --- a/gdk/win32/gdkdisplay-win32.c +++ b/gdk/win32/gdkdisplay-win32.c @@ -36,6 +36,12 @@ _gdk_windowing_set_default_display (GdkDisplay *display) g_assert (display == NULL || _gdk_display == display); } +gulong +_gdk_windowing_window_get_next_serial (GdkDisplay *display) +{ + return 0; +} + #ifdef HAVE_MONITOR_INFO static BOOL CALLBACK count_monitor (HMONITOR hmonitor, @@ -200,7 +206,7 @@ gdk_display_open (const gchar *display_name) _gdk_visual_init (); gdk_screen_set_default_colormap (_gdk_screen, gdk_screen_get_system_colormap (_gdk_screen)); - _gdk_windowing_window_init (); + _gdk_windowing_window_init (_gdk_screen); _gdk_windowing_image_init (); _gdk_events_init (); _gdk_input_init (_gdk_display); diff --git a/gdk/win32/gdkdrawable-win32.c b/gdk/win32/gdkdrawable-win32.c index e762ae0f05..52ab3fbb81 100644 --- a/gdk/win32/gdkdrawable-win32.c +++ b/gdk/win32/gdkdrawable-win32.c @@ -92,7 +92,8 @@ static void gdk_win32_draw_drawable (GdkDrawable *drawable, gint xdest, gint ydest, gint width, - gint height); + gint height, + GdkDrawable *original_src); static void gdk_win32_draw_points (GdkDrawable *drawable, GdkGC *gc, GdkPoint *points, @@ -114,6 +115,18 @@ static void gdk_win32_draw_image (GdkDrawable *drawable, gint ydest, gint width, gint height); +static void gdk_win32_draw_pixbuf (GdkDrawable *drawable, + GdkGC *gc, + GdkPixbuf *pixbuf, + gint src_x, + gint src_y, + gint dest_x, + gint dest_y, + gint width, + gint height, + GdkRgbDither dither, + gint x_dither, + gint y_dither); static cairo_surface_t *gdk_win32_ref_cairo_surface (GdkDrawable *drawable); @@ -128,49 +141,19 @@ static GdkScreen * gdk_win32_get_screen (GdkDrawable *drawable); static GdkVisual* gdk_win32_get_visual (GdkDrawable *drawable); -static void gdk_drawable_impl_win32_class_init (GdkDrawableImplWin32Class *klass); - static void gdk_drawable_impl_win32_finalize (GObject *object); -static gpointer parent_class = NULL; static const cairo_user_data_key_t gdk_win32_cairo_key; -GType -gdk_drawable_impl_win32_get_type (void) -{ - static GType object_type = 0; +G_DEFINE_TYPE (GdkDrawableImplWin32, _gdk_drawable_impl_win32, GDK_TYPE_DRAWABLE) - if (!object_type) - { - static const GTypeInfo object_info = - { - sizeof (GdkDrawableImplWin32Class), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) gdk_drawable_impl_win32_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (GdkDrawableImplWin32), - 0, /* n_preallocs */ - (GInstanceInitFunc) NULL, - }; - - object_type = g_type_register_static (GDK_TYPE_DRAWABLE, - "GdkDrawableImplWin32", - &object_info, 0); - } - - return object_type; -} static void -gdk_drawable_impl_win32_class_init (GdkDrawableImplWin32Class *klass) +_gdk_drawable_impl_win32_class_init (GdkDrawableImplWin32Class *klass) { GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass); - parent_class = g_type_class_peek_parent (klass); - object_class->finalize = gdk_drawable_impl_win32_finalize; drawable_class->create_gc = _gdk_win32_gc_new; @@ -179,11 +162,12 @@ gdk_drawable_impl_win32_class_init (GdkDrawableImplWin32Class *klass) drawable_class->draw_polygon = gdk_win32_draw_polygon; drawable_class->draw_text = gdk_win32_draw_text; drawable_class->draw_text_wc = gdk_win32_draw_text_wc; - drawable_class->draw_drawable = gdk_win32_draw_drawable; + drawable_class->draw_drawable_with_src = gdk_win32_draw_drawable; drawable_class->draw_points = gdk_win32_draw_points; drawable_class->draw_segments = gdk_win32_draw_segments; drawable_class->draw_lines = gdk_win32_draw_lines; drawable_class->draw_image = gdk_win32_draw_image; + drawable_class->draw_pixbuf = gdk_win32_draw_pixbuf; drawable_class->ref_cairo_surface = gdk_win32_ref_cairo_surface; @@ -197,12 +181,17 @@ gdk_drawable_impl_win32_class_init (GdkDrawableImplWin32Class *klass) drawable_class->_copy_to_image = _gdk_win32_copy_to_image; } +static void +_gdk_drawable_impl_win32_init (GdkDrawableImplWin32 *impl) +{ +} + static void gdk_drawable_impl_win32_finalize (GObject *object) { gdk_drawable_set_colormap (GDK_DRAWABLE (object), NULL); - G_OBJECT_CLASS (parent_class)->finalize (object); + G_OBJECT_CLASS (_gdk_drawable_impl_win32_parent_class)->finalize (object); } /***************************************************** @@ -225,10 +214,10 @@ gdk_win32_set_colormap (GdkDrawable *drawable, return; if (impl->colormap) - gdk_colormap_unref (impl->colormap); + g_object_unref (impl->colormap); impl->colormap = colormap; if (impl->colormap) - gdk_colormap_ref (impl->colormap); + g_object_ref (impl->colormap); } /* Drawing @@ -505,7 +494,7 @@ draw_tiles (GdkDrawable *drawable, gdk_win32_hdc_release (drawable, gc, mask); gdk_win32_hdc_release (tile, gc_copy, mask); - gdk_gc_unref (gc_copy); + g_object_unref (gc_copy); } static void @@ -640,11 +629,11 @@ generic_draw (GdkDrawable *drawable, gdk_draw_rectangle (tile_pixmap, tile_gc, TRUE, 0, 0, width, height); } - gdk_gc_unref (stipple_gc); + g_object_unref (stipple_gc); } - gdk_gc_unref (mask_gc); - gdk_gc_unref (tile_gc); + g_object_unref (mask_gc); + g_object_unref (tile_gc); mask_hdc = CreateCompatibleDC (hdc); @@ -1148,7 +1137,8 @@ gdk_win32_draw_drawable (GdkDrawable *drawable, gint xdest, gint ydest, gint width, - gint height) + gint height, + GdkDrawable *original_src) { g_assert (GDK_IS_DRAWABLE_IMPL_WIN32 (drawable)); @@ -1657,16 +1647,45 @@ _gdk_win32_blit (gboolean use_fg_bg, else g_assert_not_reached (); + if (GDK_IS_WINDOW_IMPL_WIN32 (draw_impl) && + GDK_IS_PIXMAP_IMPL_WIN32 (src_impl)) + { + GdkPixmapImplWin32 *src_pixmap = GDK_PIXMAP_IMPL_WIN32 (src_impl); + + if (xsrc < 0) + { + width += xsrc; + xdest -= xsrc; + xsrc = 0; + } + + if (ysrc < 0) + { + height += ysrc; + ydest -= ysrc; + ysrc = 0; + } + + if (xsrc + width > src_pixmap->width) + width = src_pixmap->width - xsrc; + if (ysrc + height > src_pixmap->height) + height = src_pixmap->height - ysrc; + } + hdc = gdk_win32_hdc_get (&draw_impl->parent_instance, gc, GDK_GC_FOREGROUND); - gdk_drawable_get_size (src, &src_width, &src_height); + gdk_drawable_get_size (src_impl->wrapper, &src_width, &src_height); if ((src_rgn = CreateRectRgn (0, 0, src_width + 1, src_height + 1)) == NULL) - WIN32_GDI_FAILED ("CreateRectRgn"); + { + WIN32_GDI_FAILED ("CreateRectRgn"); + } else if ((draw_rgn = CreateRectRgn (xsrc, ysrc, xsrc + width + 1, ysrc + height + 1)) == NULL) - WIN32_GDI_FAILED ("CreateRectRgn"); + { + WIN32_GDI_FAILED ("CreateRectRgn"); + } else { if (GDK_IS_WINDOW_IMPL_WIN32 (draw_impl)) @@ -1731,6 +1750,7 @@ _gdk_win32_blit (gboolean use_fg_bg, xsrc, ysrc, xdest, ydest, width, height); else blit_from_window (hdc, GDK_GC_WIN32 (gc), src_impl, xsrc, ysrc, xdest, ydest, width, height); + gdk_win32_hdc_release (&draw_impl->parent_instance, gc, GDK_GC_FOREGROUND); } @@ -1752,6 +1772,27 @@ gdk_win32_draw_image (GdkDrawable *drawable, xsrc, ysrc, xdest, ydest, width, height); } +static void +gdk_win32_draw_pixbuf (GdkDrawable *drawable, + GdkGC *gc, + GdkPixbuf *pixbuf, + gint src_x, + gint src_y, + gint dest_x, + gint dest_y, + gint width, + gint height, + GdkRgbDither dither, + gint x_dither, + gint y_dither) +{ + GdkDrawable *wrapper = GDK_DRAWABLE_IMPL_WIN32 (drawable)->wrapper; + GDK_DRAWABLE_CLASS (_gdk_drawable_impl_win32_parent_class)->draw_pixbuf (wrapper, gc, pixbuf, + src_x, src_y, dest_x, dest_y, + width, height, + dither, x_dither, y_dither); +} + /** * _gdk_win32_drawable_acquire_dc * @drawable: a Win32 #GdkDrawable implementation @@ -1807,7 +1848,9 @@ _gdk_win32_drawable_acquire_dc (GdkDrawable *drawable) return impl->hdc; } else - return NULL; + { + return NULL; + } } /** @@ -1844,6 +1887,15 @@ _gdk_win32_drawable_release_dc (GdkDrawable *drawable) } } +cairo_surface_t * +_gdk_windowing_create_cairo_surface (GdkDrawable *drawable, + gint width, + gint height) +{ + /* width and height are determined from the DC */ + return gdk_win32_ref_cairo_surface (drawable); +} + static void gdk_win32_cairo_surface_destroy (void *data) { @@ -1879,6 +1931,14 @@ gdk_win32_ref_cairo_surface (GdkDrawable *drawable) return impl->cairo_surface; } +void +_gdk_windowing_set_cairo_surface_size (cairo_surface_t *surface, + gint width, + gint height) +{ + // Do nothing. The surface size is determined by the DC +} + static gint gdk_win32_get_depth (GdkDrawable *drawable) { @@ -1922,10 +1982,9 @@ _gdk_win32_drawable_finish (GdkDrawable *drawable) if (impl->cairo_surface) { cairo_surface_finish (impl->cairo_surface); - cairo_surface_set_user_data (impl->cairo_surface, &gdk_win32_cairo_key, - NULL, NULL); + cairo_surface_set_user_data (impl->cairo_surface, &gdk_win32_cairo_key, NULL, NULL); } - + g_assert (impl->hdc_count == 0); } diff --git a/gdk/win32/gdkdrawable-win32.h b/gdk/win32/gdkdrawable-win32.h index d11ee6ad93..32649d8403 100644 --- a/gdk/win32/gdkdrawable-win32.h +++ b/gdk/win32/gdkdrawable-win32.h @@ -38,7 +38,7 @@ G_BEGIN_DECLS typedef struct _GdkDrawableImplWin32 GdkDrawableImplWin32; typedef struct _GdkDrawableImplWin32Class GdkDrawableImplWin32Class; -#define GDK_TYPE_DRAWABLE_IMPL_WIN32 (gdk_drawable_impl_win32_get_type ()) +#define GDK_TYPE_DRAWABLE_IMPL_WIN32 (_gdk_drawable_impl_win32_get_type ()) #define GDK_DRAWABLE_IMPL_WIN32(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_DRAWABLE_IMPL_WIN32, GdkDrawableImplWin32)) #define GDK_DRAWABLE_IMPL_WIN32_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_DRAWABLE_IMPL_WIN32, GdkDrawableImplWin32Class)) #define GDK_IS_DRAWABLE_IMPL_WIN32(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_DRAWABLE_IMPL_WIN32)) @@ -61,10 +61,9 @@ struct _GdkDrawableImplWin32 struct _GdkDrawableImplWin32Class { GdkDrawableClass parent_class; - }; -GType gdk_drawable_impl_win32_get_type (void); +GType _gdk_drawable_impl_win32_get_type (void); HDC _gdk_win32_drawable_acquire_dc (GdkDrawable *drawable); void _gdk_win32_drawable_release_dc (GdkDrawable *drawable); diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c index 3cdd66f0e1..9a3c9190b5 100644 --- a/gdk/win32/gdkevents-win32.c +++ b/gdk/win32/gdkevents-win32.c @@ -1,7 +1,8 @@ /* GDK - The GIMP Drawing Kit * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald * Copyright (C) 1998-2002 Tor Lillqvist - * Copyright (C) 2007-2008 Cody Russell + * Copyright (C) 2001,2009 Hans Breuer + * Copyright (C) 2007-2009 Cody Russell * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -99,16 +100,6 @@ static gboolean is_modally_blocked (GdkWindow *window); /* Private variable declarations */ -static GdkWindow *p_grab_window = NULL; /* Window that currently holds - * the pointer grab - */ - -static GdkWindow *p_grab_confine_to = NULL; - -static GdkWindow *k_grab_window = NULL; /* Window the holds the - * keyboard grab - */ - static GList *client_filters; /* Filters for client messages */ static gboolean p_grab_automatic; @@ -125,7 +116,7 @@ static GSourceFuncs event_funcs = { GPollFD event_poll_fd; -static GdkWindow *current_window = NULL; +static GdkWindow *current_toplevel = NULL; static gint current_x, current_y; static gint current_root_x, current_root_y; static UINT client_message; @@ -271,7 +262,7 @@ inner_window_procedure (HWND hwnd, else { /* Otherwise call DefWindowProcW(). */ - GDK_NOTE (EVENTS, g_print (" DefWindowProcW")); + GDK_NOTE (EVENTLOOP, g_print (" DefWindowProcW")); return DefWindowProcW (hwnd, message, wparam, lparam); } } @@ -475,16 +466,17 @@ event_mask_string (GdkEventMask mask) } GdkGrabStatus -gdk_pointer_grab (GdkWindow *window, - gboolean owner_events, - GdkEventMask event_mask, - GdkWindow *confine_to, - GdkCursor *cursor, - guint32 time) +_gdk_windowing_pointer_grab (GdkWindow *window, + GdkWindow *native_window, + gboolean owner_events, + GdkEventMask event_mask, + GdkWindow *confine_to, + GdkCursor *cursor, + guint32 time) { HCURSOR hcursor; GdkCursorPrivate *cursor_private; - gint return_val = GDK_GRAB_SUCCESS; + gint return_val; g_return_val_if_fail (window != NULL, 0); g_return_val_if_fail (GDK_IS_WINDOW (window), 0); @@ -497,7 +489,7 @@ gdk_pointer_grab (GdkWindow *window, else if ((hcursor = CopyCursor (cursor_private->hcursor)) == NULL) WIN32_API_FAILED ("CopyCursor"); - return_val = _gdk_input_grab_pointer (window, + return_val = _gdk_input_grab_pointer (native_window, owner_events, event_mask, confine_to, @@ -505,36 +497,10 @@ gdk_pointer_grab (GdkWindow *window, if (return_val == GDK_GRAB_SUCCESS) { - if (!GDK_WINDOW_DESTROYED (window)) - { - GDK_NOTE (EVENTS, g_print ("%sgdk_pointer_grab: %p %s %p %s%s", - (debug_indent > 0 ? "\n" : ""), - GDK_WINDOW_HWND (window), - (owner_events ? "TRUE" : "FALSE"), - hcursor, - event_mask_string (event_mask), - (debug_indent == 0 ? "\n" : ""))); - - p_grab_mask = event_mask; - p_grab_owner_events = owner_events; - p_grab_automatic = FALSE; - - SetCapture (GDK_WINDOW_HWND (window)); - return_val = GDK_GRAB_SUCCESS; - } - else - return_val = GDK_GRAB_ALREADY_GRABBED; - } - - if (return_val == GDK_GRAB_SUCCESS) - { - GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl); - - if (p_grab_window != NULL && p_grab_window != window) - generate_grab_broken_event (p_grab_window, FALSE, window); - - assign_object (&p_grab_window, window); + GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) native_window)->impl); + SetCapture (GDK_WINDOW_HWND (native_window)); + /* TODO_CSW: grab brokens, confine window, input_grab */ if (p_grab_cursor != NULL) { if (GetCursor () == p_grab_cursor) @@ -551,28 +517,8 @@ gdk_pointer_grab (GdkWindow *window, else SetCursor (LoadCursor (NULL, IDC_ARROW)); - if (confine_to != NULL) - { - gint x, y, width, height; - RECT rect; - - gdk_window_get_origin (confine_to, &x, &y); - gdk_drawable_get_size (confine_to, &width, &height); - - x -= _gdk_offset_x; - y -= _gdk_offset_y; - - rect.left = x; - rect.top = y; - rect.right = x + width; - rect.bottom = y + height; - API_CALL (ClipCursor, (&rect)); - p_grab_confine_to = confine_to; - } - - /* FIXME: Generate GDK_CROSSING_GRAB events */ } - + return return_val; } @@ -580,44 +526,32 @@ void gdk_display_pointer_ungrab (GdkDisplay *display, guint32 time) { - g_return_if_fail (display == _gdk_display); + GdkPointerGrabInfo *info; - GDK_NOTE (EVENTS, g_print ("%sgdk_display_pointer_ungrab%s", - (debug_indent > 0 ? "\n" : ""), - (debug_indent == 0 ? "\n" : ""))); - - _gdk_input_ungrab_pointer (time); - - if (GetCapture () != NULL) - ReleaseCapture (); - - /* FIXME: Generate GDK_CROSSING_UNGRAB events */ - - assign_object (&p_grab_window, NULL); - if (p_grab_cursor != NULL) + info = _gdk_display_get_last_pointer_grab (display); + if (info) { - if (GetCursor () == p_grab_cursor) - SetCursor (NULL); - DestroyCursor (p_grab_cursor); - p_grab_cursor = NULL; + info->serial_end = 0; + ReleaseCapture (); } + /* TODO_CSW: cursor, confines, etc */ - if (p_grab_confine_to != NULL) - { - API_CALL (ClipCursor, (NULL)); - p_grab_confine_to = NULL; - } + _gdk_display_pointer_grab_update (display, 0); } + static GdkWindow * -find_real_window_for_grabbed_mouse_event (GdkWindow* reported_window, - MSG* msg) +find_window_for_mouse_event (GdkWindow* reported_window, + MSG* msg) { HWND hwnd; POINTS points; POINT pt; GdkWindow* other_window = NULL; + if (!_gdk_display_get_last_pointer_grab (_gdk_display)) + return reported_window; + points = MAKEPOINTS (msg->lParam); pt.x = points.x; pt.y = points.y; @@ -640,162 +574,50 @@ find_real_window_for_grabbed_mouse_event (GdkWindow* reported_window, if (other_window == NULL) return _gdk_root; + /* need to also adjust the coordinates to the new window */ + pt.x = points.x; + pt.y = points.y; + ClientToScreen (msg->hwnd, &pt); + ScreenToClient (GDK_WINDOW_HWND (other_window), &pt); + /* ATTENTION: need to update client coords */ + msg->lParam = MAKELPARAM (pt.x, pt.y); + return other_window; } -static GdkWindow* -find_window_for_mouse_event (GdkWindow* reported_window, - MSG* msg) -{ - if (p_grab_window == NULL || !p_grab_owner_events) - return reported_window; - else - return find_real_window_for_grabbed_mouse_event (reported_window, msg); -} - -gboolean -gdk_display_pointer_is_grabbed (GdkDisplay *display) -{ - g_return_val_if_fail (display == _gdk_display, FALSE); - GDK_NOTE (EVENTS, g_print ("gdk_pointer_is_grabbed: %s\n", - p_grab_window != NULL ? "TRUE" : "FALSE")); - return p_grab_window != NULL; -} - -gboolean -gdk_pointer_grab_info_libgtk_only (GdkDisplay *display, - GdkWindow **grab_window, - gboolean *owner_events) -{ - g_return_val_if_fail (display == _gdk_display, FALSE); - - if (p_grab_window != NULL) - { - if (grab_window) - *grab_window = p_grab_window; - if (owner_events) - *owner_events = p_grab_owner_events; - - return TRUE; - } - else - return FALSE; -} - GdkGrabStatus gdk_keyboard_grab (GdkWindow *window, gboolean owner_events, guint32 time) { - GdkWindow *real_focus_window, *grab_focus_window; + GdkDisplay *display; + GdkWindow *toplevel; - gint return_val; - g_return_val_if_fail (window != NULL, 0); g_return_val_if_fail (GDK_IS_WINDOW (window), 0); GDK_NOTE (EVENTS, g_print ("gdk_keyboard_grab %p%s\n", GDK_WINDOW_HWND (window), owner_events ? " OWNER_EVENTS" : "")); - if (!GDK_WINDOW_DESTROYED (window)) - { - k_grab_owner_events = owner_events; - return_val = GDK_GRAB_SUCCESS; - } - else - return_val = GDK_GRAB_ALREADY_GRABBED; + display = gdk_drawable_get_display (window); + toplevel = gdk_window_get_toplevel (window); - if (return_val == GDK_GRAB_SUCCESS) - { - if (k_grab_window != NULL && k_grab_window != window) - generate_grab_broken_event (k_grab_window, TRUE, window); + _gdk_display_set_has_keyboard_grab (display, + window, + toplevel, + owner_events, + 0, + time); - assign_object (&k_grab_window, window); - - if (!k_grab_owner_events) - { - real_focus_window = gdk_win32_handle_table_lookup ((GdkNativeWindow) GetFocus ()); - if (real_focus_window) - real_focus_window = gdk_window_get_toplevel (real_focus_window); - grab_focus_window = gdk_window_get_toplevel (k_grab_window); - if (real_focus_window != grab_focus_window) - { - /* Generate events for focus change from the window that really - * has focus to the grabber. - */ - if (real_focus_window && !GDK_WINDOW_DESTROYED (real_focus_window) - && (((GdkWindowObject *) real_focus_window)->event_mask - & GDK_FOCUS_CHANGE_MASK)) - generate_focus_event (real_focus_window, FALSE); - - if (((GdkWindowObject *) grab_focus_window)->event_mask - & GDK_FOCUS_CHANGE_MASK) - generate_focus_event (grab_focus_window, TRUE); - } - } - } - - return return_val; + return GDK_GRAB_SUCCESS; } void gdk_display_keyboard_ungrab (GdkDisplay *display, guint32 time) { - GdkWindow *real_focus_window, *grab_focus_window; - - g_return_if_fail (display == _gdk_display); - GDK_NOTE (EVENTS, g_print ("gdk_display_keyboard_ungrab\n")); - - if (k_grab_window && !k_grab_owner_events) - { - real_focus_window = gdk_win32_handle_table_lookup ((GdkNativeWindow) GetFocus ()); - if (real_focus_window) - real_focus_window = gdk_window_get_toplevel (real_focus_window); - if (!GDK_WINDOW_DESTROYED (k_grab_window)) - grab_focus_window = gdk_window_get_toplevel (k_grab_window); - else - grab_focus_window = NULL; - if (real_focus_window != grab_focus_window) - { - /* Generate events for focus change from grabber to the window that - * really has focus. Important for example if a new window is created - * while focus is grabbed. - */ - if (grab_focus_window - && (((GdkWindowObject *) grab_focus_window)->event_mask - & GDK_FOCUS_CHANGE_MASK)) - generate_focus_event (grab_focus_window, FALSE); - - if (real_focus_window && !GDK_WINDOW_DESTROYED (real_focus_window) - && (((GdkWindowObject *) real_focus_window)->event_mask - & GDK_FOCUS_CHANGE_MASK)) - generate_focus_event (real_focus_window, TRUE); - } - } - - assign_object (&k_grab_window, NULL); -} - -gboolean -gdk_keyboard_grab_info_libgtk_only (GdkDisplay *display, - GdkWindow **grab_window, - gboolean *owner_events) -{ - g_return_val_if_fail (display == _gdk_display, FALSE); - - if (k_grab_window) - { - if (grab_window) - *grab_window = k_grab_window; - if (owner_events) - *owner_events = k_grab_owner_events; - - return TRUE; - } - else - return FALSE; + _gdk_display_unset_has_keyboard_grab (display, FALSE); } void @@ -808,7 +630,7 @@ gdk_display_add_client_message_filter (GdkDisplay *display, gdk_add_client_message_filter (message_type, func, data); } -void +void gdk_add_client_message_filter (GdkAtom message_type, GdkFilterFunc func, gpointer data) @@ -952,7 +774,7 @@ print_event_state (guint state) } static void -print_event (GdkEvent *event) +print_event (const GdkEvent *event) { gchar *escaped, *kvname; gchar *selection_name, *target_name, *property_name; @@ -1163,9 +985,17 @@ fixup_event (GdkEvent *event) static void append_event (GdkEvent *event) { + GList *link; + fixup_event (event); +#if 1 + link = _gdk_event_queue_append (_gdk_display, event); + /* event morphing, the passed in may not be valid afterwards */ + _gdk_windowing_got_event (_gdk_display, link, event, 0); +#else _gdk_event_queue_append (_gdk_display, event); GDK_NOTE (EVENTS, print_event (event)); +#endif } static void @@ -1388,201 +1218,34 @@ synthesize_enter_or_leave_event (GdkWindow *window, MSG *msg, GdkEventType type, GdkCrossingMode mode, - GdkNotifyType detail, - gint x, - gint y) + GdkNotifyType detail) { GdkEvent *event; - gint xoffset, yoffset; + POINT pt; + + pt = msg->pt; + ScreenToClient (GDK_WINDOW_HWND (window), &pt); event = gdk_event_new (type); event->crossing.window = window; event->crossing.subwindow = NULL; event->crossing.time = _gdk_win32_get_next_tick (msg->time); - _gdk_win32_windowing_window_get_offsets (window, &xoffset, &yoffset); - event->crossing.x = x + xoffset; - event->crossing.y = y + yoffset; + event->crossing.x = pt.x; + event->crossing.y = pt.y; event->crossing.x_root = msg->pt.x + _gdk_offset_x; event->crossing.y_root = msg->pt.y + _gdk_offset_y; event->crossing.mode = mode; event->crossing.detail = detail; event->crossing.focus = TRUE; /* FIXME: Set correctly */ event->crossing.state = 0; /* FIXME: Set correctly */ - + append_event (event); if (type == GDK_ENTER_NOTIFY && ((GdkWindowObject *) window)->extension_events != 0) _gdk_input_enter_event (window); } - -static void -synthesize_leave_event (GdkWindow *window, - MSG *msg, - GdkCrossingMode mode, - GdkNotifyType detail) -{ - POINT pt; - - if (p_grab_window != NULL && !p_grab_owner_events && !(p_grab_mask & GDK_LEAVE_NOTIFY_MASK)) - return; - - if (!(((GdkWindowObject *) window)->event_mask & GDK_LEAVE_NOTIFY_MASK)) - return; - - /* Leave events are at (current_x,current_y) in current_window */ - - if (current_window != window) - { - pt.x = current_x; - pt.y = current_y; - ClientToScreen (GDK_WINDOW_HWND (current_window), &pt); - ScreenToClient (GDK_WINDOW_HWND (window), &pt); - synthesize_enter_or_leave_event (window, msg, GDK_LEAVE_NOTIFY, mode, detail, pt.x, pt.y); - } - else - synthesize_enter_or_leave_event (window, msg, GDK_LEAVE_NOTIFY, mode, detail, current_x, current_y); - - /* This would only make sense if the WM_MOUSEMOVE messages would come - * before the respective WM_MOUSELEAVE message, which apparently they - * do not. - track_mouse_event (TME_CANCEL, msg->hwnd); - */ -} - -static void -synthesize_enter_event (GdkWindow *window, - MSG *msg, - GdkCrossingMode mode, - GdkNotifyType detail) -{ - POINT pt; - - if (p_grab_window != NULL && !p_grab_owner_events && !(p_grab_mask & GDK_ENTER_NOTIFY_MASK)) - return; - - if (!(((GdkWindowObject *) window)->event_mask & GDK_ENTER_NOTIFY_MASK)) - return; - - /* Enter events are at GET_X_LPARAM (msg->lParam), GET_Y_LPARAM - * (msg->lParam) in msg->hwnd - */ - - pt.x = GET_X_LPARAM (msg->lParam); - pt.y = GET_Y_LPARAM (msg->lParam); - if (msg->hwnd != GDK_WINDOW_HWND (window)) - { - ClientToScreen (msg->hwnd, &pt); - ScreenToClient (GDK_WINDOW_HWND (window), &pt); - } - synthesize_enter_or_leave_event (window, msg, GDK_ENTER_NOTIFY, mode, detail, pt.x, pt.y); - - track_mouse_event (TME_LEAVE, GDK_WINDOW_HWND (window)); -} - -static void -synthesize_enter_events (GdkWindow *from, - GdkWindow *to, - MSG *msg, - GdkCrossingMode mode, - GdkNotifyType detail) -{ - GdkWindow *prev = gdk_window_get_parent (to); - - if (prev != from) - synthesize_enter_events (from, prev, msg, mode, detail); - synthesize_enter_event (to, msg, mode, detail); -} -static void -synthesize_leave_events (GdkWindow *from, - GdkWindow *to, - MSG *msg, - GdkCrossingMode mode, - GdkNotifyType detail) -{ - GdkWindow *next = gdk_window_get_parent (from); - - synthesize_leave_event (from, msg, mode, detail); - if (next != to) - synthesize_leave_events (next, to, msg, mode, detail); -} - -static void -synthesize_crossing_events (GdkWindow *window, - GdkCrossingMode mode, - MSG *msg) -{ - GdkWindow *intermediate, *tem, *common_ancestor; - - if (gdk_window_is_ancestor (current_window, window)) - { - /* Pointer has moved to an inferior window. */ - synthesize_leave_event (current_window, msg, mode, GDK_NOTIFY_INFERIOR); - - /* If there are intermediate windows, generate ENTER_NOTIFY - * events for them - */ - intermediate = gdk_window_get_parent (window); - if (intermediate != current_window) - { - synthesize_enter_events (current_window, intermediate, msg, mode, GDK_NOTIFY_VIRTUAL); - } - - synthesize_enter_event (window, msg, mode, GDK_NOTIFY_ANCESTOR); - } - else if (gdk_window_is_ancestor (window, current_window)) - { - /* Pointer has moved to an ancestor window. */ - synthesize_leave_event (current_window, msg, mode, GDK_NOTIFY_ANCESTOR); - - /* If there are intermediate windows, generate LEAVE_NOTIFY - * events for them - */ - intermediate = gdk_window_get_parent (current_window); - if (intermediate != window) - { - synthesize_leave_events (intermediate, window, msg, mode, GDK_NOTIFY_VIRTUAL); - } - - synthesize_enter_event (window, msg, mode, GDK_NOTIFY_INFERIOR); - } - else if (current_window) - { - /* Find least common ancestor of current_window and window */ - tem = current_window; - do { - common_ancestor = gdk_window_get_parent (tem); - tem = common_ancestor; - } while (common_ancestor && - !gdk_window_is_ancestor (common_ancestor, window)); - if (common_ancestor) - { - synthesize_leave_event (current_window, msg, mode, GDK_NOTIFY_NONLINEAR); - intermediate = gdk_window_get_parent (current_window); - if (intermediate != common_ancestor) - { - synthesize_leave_events (intermediate, common_ancestor, - msg, mode, GDK_NOTIFY_NONLINEAR_VIRTUAL); - } - intermediate = gdk_window_get_parent (window); - if (intermediate != common_ancestor) - { - synthesize_enter_events (common_ancestor, intermediate, - msg, mode, GDK_NOTIFY_NONLINEAR_VIRTUAL); - } - synthesize_enter_event (window, msg, mode, GDK_NOTIFY_NONLINEAR); - } - } - else - { - /* Dunno where we are coming from */ - synthesize_enter_event (window, msg, mode, GDK_NOTIFY_UNKNOWN); - } - - assign_object (¤t_window, window); -} - static void synthesize_expose_events (GdkWindow *window) { @@ -1855,10 +1518,12 @@ handle_configure_event (MSG *msg, { RECT client_rect; POINT point; + GdkWindowObject *window_object; GetClientRect (msg->hwnd, &client_rect); point.x = client_rect.left; /* always 0 */ point.y = client_rect.top; + /* top level windows need screen coords */ if (gdk_window_get_parent (window) == _gdk_root) { @@ -1867,13 +1532,17 @@ handle_configure_event (MSG *msg, point.y += _gdk_offset_y; } - GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->width = client_rect.right - client_rect.left; - GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->height = client_rect.bottom - client_rect.top; + window_object = GDK_WINDOW_OBJECT (window); + + window_object->width = client_rect.right - client_rect.left; + window_object->height = client_rect.bottom - client_rect.top; - ((GdkWindowObject *) window)->x = point.x; - ((GdkWindowObject *) window)->y = point.y; + window_object->x = point.x; + window_object->y = point.y; + + _gdk_window_update_size (window); - if (((GdkWindowObject *) window)->event_mask & GDK_STRUCTURE_MASK) + if (window_object->event_mask & GDK_STRUCTURE_MASK) { GdkEvent *event = gdk_event_new (GDK_CONFIGURE); @@ -1953,7 +1622,6 @@ handle_wm_paint (MSG *msg, HDC hdc; PAINTSTRUCT paintstruct; GdkRegion *update_region; - gint xoffset, yoffset; if (GetUpdateRgn (msg->hwnd, hrgn, FALSE) == ERROR) { @@ -1972,29 +1640,6 @@ handle_wm_paint (MSG *msg, EndPaint (msg->hwnd, &paintstruct); - /* HB: don't generate GDK_EXPOSE events for InputOnly - * windows -> backing store now works! - */ - if (((GdkWindowObject *) window)->input_only) - { - DeleteObject (hrgn); - return; - } - - if (!(((GdkWindowObject *) window)->event_mask & GDK_EXPOSURE_MASK)) - { - GDK_NOTE (EVENTS, g_print (" (ignored)")); - DeleteObject (hrgn); - return; - } - -#if 0 /* we need to process exposes even with GDK_NO_BG - * Otherwise The GIMP canvas update is broken .... - */ - if (((GdkWindowObject *) window)->bg_pixmap == GDK_NO_BG) - break; -#endif - if ((paintstruct.rcPaint.right == paintstruct.rcPaint.left) || (paintstruct.rcPaint.bottom == paintstruct.rcPaint.top)) { @@ -2036,11 +1681,8 @@ handle_wm_paint (MSG *msg, } update_region = _gdk_win32_hrgn_to_region (hrgn); - - _gdk_win32_windowing_window_get_offsets (window, &xoffset, &yoffset); - gdk_region_offset (update_region, xoffset, yoffset); - - _gdk_window_process_expose (window, update_region); + if (!gdk_region_empty (update_region)) + _gdk_window_invalidate_for_expose (window, update_region); gdk_region_destroy (update_region); DeleteObject (hrgn); @@ -2093,21 +1735,14 @@ static void generate_button_event (GdkEventType type, gint button, GdkWindow *window, - GdkWindow *orig_window, MSG *msg) { GdkEvent *event = gdk_event_new (type); - gint xoffset, yoffset; event->button.window = window; event->button.time = _gdk_win32_get_next_tick (msg->time); - if (window != orig_window) - translate_mouse_coords (orig_window, window, msg); event->button.x = current_x = (gint16) GET_X_LPARAM (msg->lParam); event->button.y = current_y = (gint16) GET_Y_LPARAM (msg->lParam); - _gdk_win32_windowing_window_get_offsets (window, &xoffset, &yoffset); - event->button.x += xoffset; - event->button.y += yoffset; event->button.x_root = msg->pt.x + _gdk_offset_x; event->button.y_root = msg->pt.y + _gdk_offset_y; event->button.axes = NULL; @@ -2116,9 +1751,6 @@ generate_button_event (GdkEventType type, event->button.device = _gdk_display->core_pointer; append_event (event); - - if (type == GDK_BUTTON_PRESS) - _gdk_event_button_generate (_gdk_display, event); } static void @@ -2282,8 +1914,12 @@ gdk_event_translate (MSG *msg, GdkWindow *window = NULL; GdkWindowImplWin32 *impl; - GdkWindow *orig_window, *new_window; - gint xoffset, yoffset; + GdkWindow *orig_window, *new_window, *toplevel; + + GdkPointerGrabInfo *grab = NULL; + GdkWindow *grab_window = NULL; + guint grab_mask = 0; + gboolean grab_owner_events = FALSE; static gint update_colors_counter = 0; gint button; @@ -2461,7 +2097,7 @@ gdk_event_translate (MSG *msg, /* Let the system handle Alt-Tab, Alt-Space and Alt-F4 unless * the keyboard is grabbed. */ - if (k_grab_window == NULL && + if (_gdk_display->keyboard_grab.window == NULL && (msg->wParam == VK_TAB || msg->wParam == VK_SPACE || msg->wParam == VK_F4)) @@ -2486,7 +2122,9 @@ gdk_event_translate (MSG *msg, break; if (!propagate (&window, msg, - k_grab_window, k_grab_owner_events, GDK_ALL_EVENTS_MASK, + _gdk_display->keyboard_grab.window, + _gdk_display->keyboard_grab.owner_events, + GDK_ALL_EVENTS_MASK, doesnt_want_key, FALSE)) break; @@ -2588,7 +2226,9 @@ gdk_event_translate (MSG *msg, break; if (!propagate (&window, msg, - k_grab_window, k_grab_owner_events, GDK_ALL_EVENTS_MASK, + _gdk_display->keyboard_grab.window, + _gdk_display->keyboard_grab.owner_events, + GDK_ALL_EVENTS_MASK, doesnt_want_char, FALSE)) break; @@ -2653,42 +2293,13 @@ gdk_event_translate (MSG *msg, GET_X_LPARAM (msg->lParam), GET_Y_LPARAM (msg->lParam))); assign_object (&window, find_window_for_mouse_event (window, msg)); - - if (p_grab_window != NULL) - { - GdkWindow *real_window = find_real_window_for_grabbed_mouse_event (window, msg); - - if (real_window != current_window) - synthesize_crossing_events (real_window, GDK_CROSSING_NORMAL, msg); - } - else - { - if (window != current_window) - synthesize_crossing_events (window, GDK_CROSSING_NORMAL, msg); - } - - if (!propagate (&window, msg, - p_grab_window, p_grab_owner_events, p_grab_mask, - doesnt_want_button_press, TRUE)) - break; - + /* TODO_CSW?: there used to some synthesize and propagate */ if (GDK_WINDOW_DESTROYED (window)) break; - /* Emulate X11's automatic active grab */ - if (!p_grab_window) - { - /* No explicit active grab, let's start one automatically */ - GDK_NOTE (EVENTS, g_print (" (automatic grab)")); - gdk_pointer_grab (window, - FALSE, - ((GdkWindowObject *) window)->event_mask, - NULL, NULL, 0); - p_grab_automatic = TRUE; - } - + /* TODO_CSW? Emulate X11's automatic active grab */ generate_button_event (GDK_BUTTON_PRESS, button, - window, orig_window, msg); + window, msg); return_val = TRUE; break; @@ -2717,20 +2328,6 @@ gdk_event_translate (MSG *msg, GET_X_LPARAM (msg->lParam), GET_Y_LPARAM (msg->lParam))); assign_object (&window, find_window_for_mouse_event (window, msg)); - - if (p_grab_window != NULL) - { - GdkWindow *real_window = find_real_window_for_grabbed_mouse_event (window, msg); - - if (real_window != current_window) - synthesize_crossing_events (real_window, GDK_CROSSING_NORMAL, msg); - } - else - { - if (window != current_window) - synthesize_crossing_events (window, GDK_CROSSING_NORMAL, msg); - } - #if 0 if (((GdkWindowObject *) window)->extension_events != 0 && _gdk_input_ignore_core) @@ -2740,24 +2337,8 @@ gdk_event_translate (MSG *msg, } #endif - if (!propagate (&window, msg, - p_grab_window, p_grab_owner_events, p_grab_mask, - doesnt_want_button_release, TRUE)) - { - } - else if (!GDK_WINDOW_DESTROYED (window)) - { - generate_button_event (GDK_BUTTON_RELEASE, button, - window, orig_window, msg); - } - - if (p_grab_window != NULL && - p_grab_automatic && - (msg->wParam & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) == 0) - { - /* Terminate automatic grab */ - gdk_pointer_ungrab (0); - } + generate_button_event (GDK_BUTTON_RELEASE, button, + window, msg); return_val = TRUE; break; @@ -2768,6 +2349,22 @@ gdk_event_translate (MSG *msg, (gpointer) msg->wParam, GET_X_LPARAM (msg->lParam), GET_Y_LPARAM (msg->lParam))); + assign_object (&window, find_window_for_mouse_event (window, msg)); + toplevel = gdk_window_get_toplevel (window); + if (current_toplevel != toplevel) + { + GDK_NOTE (EVENTS, g_print (" toplevel %p -> %p", + current_toplevel ? GDK_WINDOW_HWND (current_toplevel) : NULL, + toplevel ? GDK_WINDOW_HWND (toplevel) : NULL)); + if (current_toplevel) + synthesize_enter_or_leave_event (current_toplevel, msg, + GDK_LEAVE_NOTIFY, GDK_CROSSING_NORMAL, GDK_NOTIFY_ANCESTOR); + synthesize_enter_or_leave_event (toplevel, msg, + GDK_ENTER_NOTIFY, GDK_CROSSING_NORMAL, GDK_NOTIFY_ANCESTOR); + assign_object (¤t_toplevel, toplevel); + track_mouse_event (TME_LEAVE, GDK_WINDOW_HWND (toplevel)); + } + /* If we haven't moved, don't create any GDK event. Windows * sends WM_MOUSEMOVE messages after a new window is shows under * the mouse, even if the mouse hasn't moved. This disturbs gtk. @@ -2779,55 +2376,11 @@ gdk_event_translate (MSG *msg, current_root_x = msg->pt.x + _gdk_offset_x; current_root_y = msg->pt.y + _gdk_offset_y; - assign_object (&window, find_window_for_mouse_event (window, msg)); - - if (p_grab_window != NULL) - { - GdkWindow *real_window = find_real_window_for_grabbed_mouse_event (window, msg); - - if (real_window != current_window) - { - if (p_grab_owner_events) - { - synthesize_crossing_events (real_window, GDK_CROSSING_NORMAL, msg); - } - else if (current_window == p_grab_window) - { - synthesize_leave_event (p_grab_window, msg, GDK_CROSSING_NORMAL, GDK_NOTIFY_ANCESTOR); - assign_object (¤t_window, _gdk_root); - } - else if (real_window == p_grab_window) - { - synthesize_enter_event (p_grab_window, msg, GDK_CROSSING_NORMAL, GDK_NOTIFY_ANCESTOR); - assign_object (¤t_window, p_grab_window); - } - } - } - else - { - if (window != current_window) - synthesize_crossing_events (window, GDK_CROSSING_NORMAL, msg); - } - - if (!propagate (&window, msg, - p_grab_window, p_grab_owner_events, p_grab_mask, - doesnt_want_button_motion, TRUE)) - break; - - if (GDK_WINDOW_DESTROYED (window)) - break; - - if (window != orig_window) - translate_mouse_coords (orig_window, window, msg); - event = gdk_event_new (GDK_MOTION_NOTIFY); event->motion.window = window; event->motion.time = _gdk_win32_get_next_tick (msg->time); event->motion.x = current_x = (gint16) GET_X_LPARAM (msg->lParam); event->motion.y = current_y = (gint16) GET_Y_LPARAM (msg->lParam); - _gdk_win32_windowing_window_get_offsets (window, &xoffset, &yoffset); - event->motion.x += xoffset; - event->motion.y += yoffset; event->motion.x_root = current_root_x; event->motion.y_root = current_root_y; event->motion.axes = NULL; @@ -2844,12 +2397,14 @@ gdk_event_translate (MSG *msg, GDK_NOTE (EVENTS, g_print (" (%d,%d)", GET_X_LPARAM (msg->lParam), GET_Y_LPARAM (msg->lParam))); - if (current_window != NULL && - (((GdkWindowObject *) current_window)->event_mask & GDK_LEAVE_NOTIFY_MASK)) +#if 0 /* TODO_CSW? */ + if (current_toplevel != NULL && + (((GdkWindowObject *) current_toplevel)->event_mask & GDK_LEAVE_NOTIFY_MASK)) { - synthesize_crossing_events (_gdk_root, GDK_CROSSING_NORMAL, msg); + synthesize_enter_or_leave_event (current_toplevel, msg, + GDK_LEAVE_NOTIFY, GDK_CROSSING_NORMAL, GDK_NOTIFY_ANCESTOR); } - +#endif break; case WM_MOUSELEAVE: @@ -2858,23 +2413,17 @@ gdk_event_translate (MSG *msg, if (!gdk_win32_handle_table_lookup ((GdkNativeWindow) WindowFromPoint (msg->pt))) { - GdkNotifyType detail; - - if (GDK_WINDOW_TYPE (current_window) != GDK_WINDOW_CHILD) - detail = GDK_NOTIFY_ANCESTOR; - else - detail = GDK_NOTIFY_UNKNOWN; - /* we are only interested if we don't know the new window */ - synthesize_enter_or_leave_event (current_window, msg, - GDK_LEAVE_NOTIFY, GDK_CROSSING_NORMAL, detail, - current_x, current_y); - assign_object (¤t_window, _gdk_root); + if (current_toplevel) + synthesize_enter_or_leave_event (current_toplevel, msg, + GDK_LEAVE_NOTIFY, GDK_CROSSING_NORMAL, GDK_NOTIFY_ANCESTOR); + assign_object (¤t_toplevel, NULL); } else { GDK_NOTE (EVENTS, g_print (" (ignored)")); } + return_val = TRUE; break; @@ -2901,14 +2450,6 @@ gdk_event_translate (MSG *msg, assign_object (&window, new_window); } - if (!propagate (&window, msg, - p_grab_window, p_grab_owner_events, p_grab_mask, - doesnt_want_scroll, TRUE)) - break; - - if (GDK_WINDOW_DESTROYED (window)) - break; - ScreenToClient (msg->hwnd, &point); event = gdk_event_new (GDK_SCROLL); @@ -2916,9 +2457,8 @@ gdk_event_translate (MSG *msg, event->scroll.direction = (((short) HIWORD (msg->wParam)) > 0) ? GDK_SCROLL_UP : GDK_SCROLL_DOWN; event->scroll.time = _gdk_win32_get_next_tick (msg->time); - _gdk_win32_windowing_window_get_offsets (window, &xoffset, &yoffset); - event->scroll.x = (gint16) point.x + xoffset; - event->scroll.y = (gint16) point.y + yoffset; + event->scroll.x = (gint16) point.x; + event->scroll.y = (gint16) point.y; event->scroll.x_root = (gint16) GET_X_LPARAM (msg->lParam) + _gdk_offset_x; event->scroll.y_root = (gint16) GET_Y_LPARAM (msg->lParam) + _gdk_offset_y; event->scroll.state = build_pointer_event_state (msg); @@ -3022,16 +2562,16 @@ gdk_event_translate (MSG *msg, break; case WM_KILLFOCUS: - if (p_grab_window != NULL && !GDK_WINDOW_DESTROYED (p_grab_window)) - generate_grab_broken_event (p_grab_window, FALSE, NULL); - - if (k_grab_window != NULL && !GDK_WINDOW_DESTROYED (k_grab_window) - && k_grab_window != p_grab_window) - generate_grab_broken_event (k_grab_window, TRUE, NULL); + if (_gdk_display->keyboard_grab.window != NULL && + !GDK_WINDOW_DESTROYED (_gdk_display->keyboard_grab.window)) + { + generate_grab_broken_event (_gdk_display->keyboard_grab.window, FALSE, NULL); + } /* fallthrough */ case WM_SETFOCUS: - if (k_grab_window != NULL && !k_grab_owner_events) + if (_gdk_display->keyboard_grab.window != NULL && + !_gdk_display->keyboard_grab.owner_events) break; if (!(((GdkWindowObject *) window)->event_mask & GDK_FOCUS_CHANGE_MASK)) @@ -3068,10 +2608,16 @@ gdk_event_translate (MSG *msg, GDK_NOTE (EVENTS, g_print (" %#x %#x", LOWORD (msg->lParam), HIWORD (msg->lParam))); - if (p_grab_window == NULL && LOWORD (msg->lParam) != HTCLIENT) + grab = _gdk_display_get_last_pointer_grab (_gdk_display); + if (grab != NULL) + { + grab_window = grab->window; + } + + if (grab_window == NULL && LOWORD (msg->lParam) != HTCLIENT) break; - if (p_grab_window != NULL && p_grab_cursor != NULL) + if (grab_window != NULL && p_grab_cursor != NULL) hcursor = p_grab_cursor; else if (!GDK_WINDOW_DESTROYED (window)) hcursor = GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->hcursor; @@ -3121,15 +2667,15 @@ gdk_event_translate (MSG *msg, SetForegroundWindow (GDK_WINDOW_HWND (impl->transient_owner)); } - if (p_grab_window == window) + grab = _gdk_display_get_last_pointer_grab (_gdk_display); + if (grab != NULL) { - gdk_pointer_ungrab (msg->time); + if (grab->window == window) + gdk_pointer_ungrab (msg->time); } - if (k_grab_window == window) - { - gdk_keyboard_ungrab (msg->time); - } + if (_gdk_display->keyboard_grab.window == window) + gdk_keyboard_ungrab (msg->time); } return_val = TRUE; @@ -3159,11 +2705,13 @@ gdk_event_translate (MSG *msg, if (msg->wParam == SIZE_MINIMIZED) { /* Don't generate any GDK event. This is *not* an UNMAP. */ - - if (p_grab_window == window) - gdk_pointer_ungrab (msg->time); - - if (k_grab_window == window) + grab = _gdk_display_get_last_pointer_grab (_gdk_display); + if (grab != NULL) + { + if (grab->window == window) + gdk_pointer_ungrab (msg->time); + } + if (_gdk_display->keyboard_grab.window == window) gdk_keyboard_ungrab (msg->time); gdk_synthesize_window_state (window, @@ -3601,13 +3149,14 @@ gdk_event_translate (MSG *msg, break; case WM_DESTROY: - if (window == current_window) - assign_object (¤t_window, _gdk_root); + grab = _gdk_display_get_last_pointer_grab (_gdk_display); + if (grab != NULL) + { + if (grab->window == window) + gdk_pointer_ungrab (msg->time); + } - if (p_grab_window == window) - gdk_pointer_ungrab (msg->time); - - if (k_grab_window == window) + if (_gdk_display->keyboard_grab.window == window) gdk_keyboard_ungrab (msg->time); if ((window != NULL) && (msg->hwnd != GetDesktopWindow ())) diff --git a/gdk/win32/gdkgc-win32.c b/gdk/win32/gdkgc-win32.c index c255f4b158..c4e234f4c1 100644 --- a/gdk/win32/gdkgc-win32.c +++ b/gdk/win32/gdkgc-win32.c @@ -572,7 +572,8 @@ gdk_win32_gc_set_dashes (GdkGC *gc, void _gdk_windowing_gc_set_clip_region (GdkGC *gc, - const GdkRegion *region) + const GdkRegion *region, + gboolean reset_origin) { GdkGCWin32 *win32_gc = GDK_GC_WIN32 (gc); @@ -596,10 +597,12 @@ _gdk_windowing_gc_set_clip_region (GdkGC *gc, win32_gc->values_mask &= ~GDK_GC_CLIP_MASK; } - gc->clip_x_origin = 0; - gc->clip_y_origin = 0; - - win32_gc->values_mask &= ~(GDK_GC_CLIP_X_ORIGIN | GDK_GC_CLIP_Y_ORIGIN); + if (reset_origin) + { + gc->clip_x_origin = 0; + gc->clip_y_origin = 0; + win32_gc->values_mask &= ~(GDK_GC_CLIP_X_ORIGIN | GDK_GC_CLIP_Y_ORIGIN); + } } void diff --git a/gdk/win32/gdkgeometry-win32.c b/gdk/win32/gdkgeometry-win32.c index 61dbf76287..6cdb860cc2 100644 --- a/gdk/win32/gdkgeometry-win32.c +++ b/gdk/win32/gdkgeometry-win32.c @@ -42,196 +42,15 @@ #include "gdk.h" /* For gdk_rectangle_intersect */ #include "gdkregion.h" #include "gdkregion-generic.h" +#include "gdkinternals.h" #include "gdkprivate-win32.h" #define SIZE_LIMIT 32767 typedef struct _GdkWindowParentPos GdkWindowParentPos; -struct _GdkWindowParentPos -{ - gint x; - gint y; - gint win32_x; - gint win32_y; - GdkRectangle clip_rect; -}; - -static void gdk_window_compute_position (GdkWindowImplWin32 *window, - GdkWindowParentPos *parent_pos, - GdkWin32PositionInfo *info); -static void gdk_window_compute_parent_pos (GdkWindowImplWin32 *window, - GdkWindowParentPos *parent_pos); - -static void gdk_window_postmove (GdkWindow *window, - GdkWindowParentPos *parent_pos, - gboolean anti_scroll); -static void gdk_window_tmp_unset_bg (GdkWindow *window); -static void gdk_window_tmp_reset_bg (GdkWindow *window); -static GdkRegion *gdk_window_clip_changed (GdkWindow *window, - GdkRectangle *old_clip, - GdkRectangle *new_clip); -static void gdk_window_post_scroll (GdkWindow *window, - GdkRegion *new_clip_region); - -void -_gdk_win32_windowing_window_get_offsets (GdkWindow *window, - gint *x_offset, - gint *y_offset) -{ - GdkWindowImplWin32 *impl = - GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl); - - *x_offset = impl->position_info.x_offset; - *y_offset = impl->position_info.y_offset; -} - -void -_gdk_window_init_position (GdkWindow *window) -{ - GdkWindowParentPos parent_pos; - GdkWindowImplWin32 *impl; - - g_return_if_fail (GDK_IS_WINDOW (window)); - - impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl); - - gdk_window_compute_parent_pos (impl, &parent_pos); - gdk_window_compute_position (impl, &parent_pos, &impl->position_info); -} - -void -_gdk_win32_window_scroll (GdkWindow *window, - gint dx, - gint dy) -{ - GdkRegion *invalidate_region; - GdkWindowImplWin32 *impl; - GdkWindowObject *obj; - GList *tmp_list; - GdkWindowParentPos parent_pos; - HRGN native_invalidate_region; - - GDK_NOTE (EVENTS, g_print ("gdk_window_scroll: %p %d,%d\n", - GDK_WINDOW_HWND (window), dx, dy)); - - obj = GDK_WINDOW_OBJECT (window); - impl = GDK_WINDOW_IMPL_WIN32 (obj->impl); - - /* Move the current invalid region */ - if (obj->update_area) - gdk_region_offset (obj->update_area, dx, dy); - - gdk_window_compute_parent_pos (impl, &parent_pos); - - parent_pos.x += obj->x; - parent_pos.y += obj->y; - parent_pos.win32_x += impl->position_info.x; - parent_pos.win32_y += impl->position_info.y; - parent_pos.clip_rect = impl->position_info.clip_rect; - - gdk_window_tmp_unset_bg (window); - - native_invalidate_region = CreateRectRgn (0, 0, 0, 0); - if (native_invalidate_region == NULL) - WIN32_API_FAILED ("CreateRectRgn"); - - API_CALL (ScrollWindowEx, (GDK_WINDOW_HWND (window), - dx, dy, NULL, NULL, - native_invalidate_region, NULL, SW_SCROLLCHILDREN)); - - if (impl->position_info.no_bg) - gdk_window_tmp_reset_bg (window); - - tmp_list = obj->children; - while (tmp_list) - { - GDK_WINDOW_OBJECT(tmp_list->data)->x += dx; - GDK_WINDOW_OBJECT(tmp_list->data)->y += dy; - gdk_window_postmove (tmp_list->data, &parent_pos, FALSE); - tmp_list = tmp_list->next; - } - - if (native_invalidate_region != NULL) - { - invalidate_region = _gdk_win32_hrgn_to_region (native_invalidate_region); - gdk_region_offset (invalidate_region, impl->position_info.x_offset, - impl->position_info.y_offset); - gdk_window_invalidate_region (window, invalidate_region, TRUE); - gdk_region_destroy (invalidate_region); - GDI_CALL (DeleteObject, (native_invalidate_region)); - } -} - -void -_gdk_win32_window_move_region (GdkWindow *window, - const GdkRegion *region, - gint dx, - gint dy) -{ - GdkRegion *invalidate_region; - GdkWindowImplWin32 *impl; - GdkWindowObject *obj; - GdkRectangle src_rect, dest_rect; - HRGN hrgn; - RECT clipRect, destRect; - - obj = GDK_WINDOW_OBJECT (window); - impl = GDK_WINDOW_IMPL_WIN32 (obj->impl); - - /* Move the current invalid region */ - if (obj->update_area) - gdk_region_offset (obj->update_area, dx, dy); - - /* impl->position_info.clip_rect isn't meaningful for toplevels */ - if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD) - src_rect = impl->position_info.clip_rect; - else - { - src_rect.x = 0; - src_rect.y = 0; - src_rect.width = impl->width; - src_rect.height = impl->height; - } - - invalidate_region = gdk_region_rectangle (&src_rect); - - dest_rect = src_rect; - dest_rect.x += dx; - dest_rect.y += dy; - gdk_rectangle_intersect (&dest_rect, &src_rect, &dest_rect); - - if (dest_rect.width > 0 && dest_rect.height > 0) - { - GdkRegion *tmp_region; - - tmp_region = gdk_region_rectangle (&dest_rect); - gdk_region_subtract (invalidate_region, tmp_region); - gdk_region_destroy (tmp_region); - } - - /* no guffaw scroll on win32 */ - hrgn = _gdk_win32_gdkregion_to_hrgn(invalidate_region, 0, 0); - gdk_region_destroy (invalidate_region); - destRect.left = dest_rect.y; - destRect.top = dest_rect.x; - destRect.right = dest_rect.x + dest_rect.width; - destRect.bottom = dest_rect.y + dest_rect.height; - clipRect.left = src_rect.y; - clipRect.top = src_rect.x; - clipRect.right = src_rect.x + src_rect.width; - clipRect.bottom = src_rect.y + src_rect.height; - - g_print ("ScrollWindowEx(%d, %d, ...) - if you see this work, remove trace;)\n", dx, dy); - API_CALL(ScrollWindowEx, (GDK_WINDOW_HWND (window), - dx, dy, /* in: scroll offsets */ - NULL, /* in: scroll rect, NULL == entire client area */ - &clipRect, /* in: restrict to */ - hrgn, /* in: update region */ - NULL, /* out: update rect */ - SW_INVALIDATE)); - API_CALL(DeleteObject, (hrgn)); -} +static void tmp_unset_bg (GdkWindow *window); +static void tmp_reset_bg (GdkWindow *window); void _gdk_window_move_resize_child (GdkWindow *window, @@ -242,424 +61,91 @@ _gdk_window_move_resize_child (GdkWindow *window, { GdkWindowImplWin32 *impl; GdkWindowObject *obj; - GdkWin32PositionInfo new_info; - GdkWindowParentPos parent_pos; - GList *tmp_list; - gint d_xoffset, d_yoffset; - gint dx, dy; gboolean is_move; gboolean is_resize; - GdkRegion *new_clip_region; - + g_return_if_fail (window != NULL); g_return_if_fail (GDK_IS_WINDOW (window)); obj = GDK_WINDOW_OBJECT (window); impl = GDK_WINDOW_IMPL_WIN32 (obj->impl); + + is_move = (x - obj->x != 0) && (y - obj->y != 0); + is_resize = obj->width != width && obj->height != height; GDK_NOTE (MISC, g_print ("_gdk_window_move_resize_child: %s@%+d%+d %dx%d@%+d%+d\n", _gdk_win32_drawable_description (window), - obj->x, obj->y, - width, height, x, y)); + obj->x, obj->y, width, height, x, y)); - dx = x - obj->x; - dy = y - obj->y; + if (width > 65535 || height > 65535) + { + g_warning ("Native children wider or taller than 65535 pixels are not supported."); - is_move = dx != 0 || dy != 0; - is_resize = impl->width != width || impl->height != height; - - if (!is_move && !is_resize) - { - GDK_NOTE (MISC, g_print ("... neither move or resize\n")); - return; - } - - GDK_NOTE (MISC, g_print ("... %s%s\n", - is_move ? "is_move " : "", - is_resize ? "is_resize" : "")); + if (width > 65535) + width = 65535; + if (height > 65535) + height = 65535; + } obj->x = x; obj->y = y; - impl->width = width; - impl->height = height; + obj->width = width; + obj->height = height; - gdk_window_compute_parent_pos (impl, &parent_pos); - gdk_window_compute_position (impl, &parent_pos, &new_info); - - new_clip_region = - gdk_window_clip_changed (window, &impl->position_info.clip_rect, &new_info.clip_rect); - - parent_pos.x += obj->x; - parent_pos.y += obj->y; - parent_pos.win32_x += new_info.x; - parent_pos.win32_y += new_info.y; - parent_pos.clip_rect = new_info.clip_rect; - - d_xoffset = new_info.x_offset - impl->position_info.x_offset; - d_yoffset = new_info.y_offset - impl->position_info.y_offset; + _gdk_win32_window_tmp_unset_parent_bg (window); + _gdk_win32_window_tmp_unset_bg (window, TRUE); - if (d_xoffset != 0 || d_yoffset != 0) - { - GDK_NOTE (MISC, g_print ("... d_offset=%+d%+d\n", d_xoffset, d_yoffset)); + GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,%d,%d,%d,%d," + "NOACTIVATE|NOZORDER%s%s)\n", + GDK_WINDOW_HWND (window), + obj->x + obj->parent->abs_x, obj->y + obj->parent->abs_y, + width, height, + (is_move ? "" : "|NOMOVE"), + (is_resize ? "" : "|NOSIZE"))); - if (!ScrollWindowEx (GDK_WINDOW_HWND (window), - -d_xoffset, -d_yoffset, /* in: scroll offsets */ - NULL, /* in: scroll rect, NULL == entire client area */ - NULL, /* in: restrict to */ - NULL, /* in: update region */ - NULL, /* out: update rect */ - SW_SCROLLCHILDREN)) - WIN32_API_FAILED ("ScrollWindowEx"); + API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL, + obj->x + obj->parent->abs_x, obj->y + obj->parent->abs_y, + width, height, + SWP_NOACTIVATE | SWP_NOZORDER | + (is_move ? 0 : SWP_NOMOVE) | + (is_resize ? 0 : SWP_NOSIZE))); - if (dx != d_xoffset || dy != d_yoffset || is_resize) - { - GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,%d,%d,%d,%d," - "NOACTIVATE|NOZORDER%s%s)\n", - GDK_WINDOW_HWND (window), - new_info.x, new_info.y, - new_info.width, new_info.height, - (is_move ? "" : "|NOMOVE"), - (is_resize ? "" : "|NOSIZE"))); - - API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL, - new_info.x, new_info.y, - new_info.width, new_info.height, - SWP_NOACTIVATE | SWP_NOZORDER | - (is_move ? 0 : SWP_NOMOVE) | - (is_resize ? 0 : SWP_NOSIZE))); - } - - if (impl->position_info.no_bg) - gdk_window_tmp_reset_bg (window); - - if (!impl->position_info.mapped && new_info.mapped && GDK_WINDOW_IS_MAPPED (obj)) - { - GDK_NOTE (MISC, g_print ("... ShowWindow(%p, SW_SHOWNA)\n", - GDK_WINDOW_HWND (window))); - ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNA); - } - - impl->position_info = new_info; - - tmp_list = obj->children; - while (tmp_list) - { - gdk_window_postmove (tmp_list->data, &parent_pos, FALSE); - tmp_list = tmp_list->next; - } - } - else - { - if (impl->position_info.mapped && !new_info.mapped) - { - GDK_NOTE (MISC, g_print ("... ShowWindow(%p, SW_HIDE)\n", - GDK_WINDOW_HWND (window))); - ShowWindow (GDK_WINDOW_HWND (window), SW_HIDE); - } - - GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,%d,%d,%d,%d," - "NOACTIVATE|NOZORDER%s%s)\n", - GDK_WINDOW_HWND (window), - new_info.x, new_info.y, - new_info.width, new_info.height, - (is_move ? "" : "|NOMOVE"), - (is_resize ? "" : "|NOSIZE"))); - - API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL, - new_info.x, new_info.y, - new_info.width, new_info.height, - SWP_NOACTIVATE | SWP_NOZORDER | - (is_move ? 0 : SWP_NOMOVE) | - (is_resize ? 0 : SWP_NOSIZE))); - - tmp_list = obj->children; - while (tmp_list) - { - gdk_window_postmove (tmp_list->data, &parent_pos, FALSE); - tmp_list = tmp_list->next; - } - - if (impl->position_info.no_bg) - gdk_window_tmp_reset_bg (window); - - if (!impl->position_info.mapped && new_info.mapped && GDK_WINDOW_IS_MAPPED (obj)) - { - GDK_NOTE (MISC, g_print ("... ShowWindow(%p, SW_SHOWNA)\n", - GDK_WINDOW_HWND (window))); - ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNA); - } - - impl->position_info = new_info; - } - if (new_clip_region) - gdk_window_post_scroll (window, new_clip_region); -} - -static void -gdk_window_compute_position (GdkWindowImplWin32 *window, - GdkWindowParentPos *parent_pos, - GdkWin32PositionInfo *info) -{ - GdkWindowObject *wrapper; - int parent_x_offset; - int parent_y_offset; - - g_return_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (window)); - - wrapper = GDK_WINDOW_OBJECT (GDK_DRAWABLE_IMPL_WIN32 (window)->wrapper); - - info->big = FALSE; - - if (window->width <= SIZE_LIMIT) - { - info->width = window->width; - info->x = parent_pos->x + wrapper->x - parent_pos->win32_x; - } - else - { - info->big = TRUE; - info->width = SIZE_LIMIT; - if (parent_pos->x + wrapper->x < -(SIZE_LIMIT/2)) - { - if (parent_pos->x + wrapper->x + window->width < (SIZE_LIMIT/2)) - info->x = parent_pos->x + wrapper->x + window->width - info->width - parent_pos->win32_x; - else - info->x = -(SIZE_LIMIT/2) - parent_pos->win32_x; - } - else - info->x = parent_pos->x + wrapper->x - parent_pos->win32_x; - } - - if (window->height <= SIZE_LIMIT) - { - info->height = window->height; - info->y = parent_pos->y + wrapper->y - parent_pos->win32_y; - } - else - { - info->big = TRUE; - info->height = SIZE_LIMIT; - if (parent_pos->y + wrapper->y < -(SIZE_LIMIT/2)) - { - if (parent_pos->y + wrapper->y + window->height < (SIZE_LIMIT/2)) - info->y = parent_pos->y + wrapper->y + window->height - info->height - parent_pos->win32_y; - else - info->y = -(SIZE_LIMIT/2) - parent_pos->win32_y; - } - else - info->y = parent_pos->y + wrapper->y - parent_pos->win32_y; - } - - parent_x_offset = parent_pos->win32_x - parent_pos->x; - parent_y_offset = parent_pos->win32_y - parent_pos->y; - - info->x_offset = parent_x_offset + info->x - wrapper->x; - info->y_offset = parent_y_offset + info->y - wrapper->y; - - /* We don't considering the clipping of toplevel windows and their immediate children - * by their parents, and simply always map those windows. - */ - if (parent_pos->clip_rect.width == G_MAXINT) - info->mapped = TRUE; - /* Check if the window would wrap around into the visible space in either direction */ - else if (info->x + parent_x_offset < parent_pos->clip_rect.x + parent_pos->clip_rect.width - 65536 || - info->x + info->width + parent_x_offset > parent_pos->clip_rect.x + 65536 || - info->y + parent_y_offset < parent_pos->clip_rect.y + parent_pos->clip_rect.height - 65536 || - info->y + info->height + parent_y_offset > parent_pos->clip_rect.y + 65536) - info->mapped = FALSE; - else - info->mapped = TRUE; - - info->no_bg = FALSE; - - if (GDK_WINDOW_TYPE (wrapper) == GDK_WINDOW_CHILD) - { - info->clip_rect.x = wrapper->x; - info->clip_rect.y = wrapper->y; - info->clip_rect.width = window->width; - info->clip_rect.height = window->height; - - gdk_rectangle_intersect (&info->clip_rect, &parent_pos->clip_rect, &info->clip_rect); - - info->clip_rect.x -= wrapper->x; - info->clip_rect.y -= wrapper->y; - } - else - { - info->clip_rect.x = 0; - info->clip_rect.y = 0; - info->clip_rect.width = G_MAXINT; - info->clip_rect.height = G_MAXINT; - } -} - -static void -gdk_window_compute_parent_pos (GdkWindowImplWin32 *window, - GdkWindowParentPos *parent_pos) -{ - GdkWindowObject *wrapper; - GdkWindowObject *parent; - GdkRectangle tmp_clip; - - int clip_xoffset = 0; - int clip_yoffset = 0; - - g_return_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (window)); - - wrapper = GDK_WINDOW_OBJECT (GDK_DRAWABLE_IMPL_WIN32 (window)->wrapper); - - parent_pos->x = 0; - parent_pos->y = 0; - parent_pos->win32_x = 0; - parent_pos->win32_y = 0; - - /* We take a simple approach here and simply consider toplevel - * windows not to clip their children on the right/bottom, since the - * size of toplevel windows is not directly under our - * control. Clipping only really matters when scrolling and - * generally we aren't going to be moving the immediate child of a - * toplevel beyond the bounds of that toplevel. - * - * We could go ahead and recompute the clips of toplevel windows and - * their descendents when we receive size notification, but it would - * probably not be an improvement in most cases. - */ - parent_pos->clip_rect.x = 0; - parent_pos->clip_rect.y = 0; - parent_pos->clip_rect.width = G_MAXINT; - parent_pos->clip_rect.height = G_MAXINT; - - parent = (GdkWindowObject *)wrapper->parent; - while (parent && parent->window_type == GDK_WINDOW_CHILD) - { - GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (parent->impl); - - tmp_clip.x = - clip_xoffset; - tmp_clip.y = - clip_yoffset; - tmp_clip.width = impl->width; - tmp_clip.height = impl->height; - - gdk_rectangle_intersect (&parent_pos->clip_rect, &tmp_clip, &parent_pos->clip_rect); - - parent_pos->x += parent->x; - parent_pos->y += parent->y; - parent_pos->win32_x += impl->position_info.x; - parent_pos->win32_y += impl->position_info.y; - - clip_xoffset += parent->x; - clip_yoffset += parent->y; - - parent = (GdkWindowObject *)parent->parent; - } -} - -static void -gdk_window_postmove (GdkWindow *window, - GdkWindowParentPos *parent_pos, - gboolean anti_scroll) -{ - GdkWindowImplWin32 *impl; - GdkWindowObject *obj; - GdkWin32PositionInfo new_info; - GList *tmp_list; - gint d_xoffset, d_yoffset; - GdkWindowParentPos this_pos; - GdkRegion *new_clip_region; - - obj = (GdkWindowObject *) window; - impl = GDK_WINDOW_IMPL_WIN32 (obj->impl); - - gdk_window_compute_position (impl, parent_pos, &new_info); - - new_clip_region = - gdk_window_clip_changed (window, &impl->position_info.clip_rect, &new_info.clip_rect); - - this_pos.x = parent_pos->x + obj->x; - this_pos.y = parent_pos->y + obj->y; - this_pos.win32_x = parent_pos->win32_x + new_info.x; - this_pos.win32_y = parent_pos->win32_y + new_info.y; - this_pos.clip_rect = new_info.clip_rect; - - if (impl->position_info.mapped && !new_info.mapped) - ShowWindow (GDK_WINDOW_HWND (window), SW_HIDE); - - d_xoffset = new_info.x_offset - impl->position_info.x_offset; - d_yoffset = new_info.y_offset - impl->position_info.y_offset; - - if (anti_scroll || (anti_scroll = d_xoffset != 0 || d_yoffset != 0)) - { - GDK_NOTE (MISC, g_print ("gdk_window_postmove: %s@%+d%+d\n" - "... SetWindowPos(%p,NULL,%d,%d,0,0," - "NOREDRAW|NOZORDER|NOACTIVATE|NOSIZE)\n", - _gdk_win32_drawable_description (window), - obj->x, obj->y, - GDK_WINDOW_HWND (window), - new_info.x, new_info.y)); - - API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL, - new_info.x, new_info.y, - 0, 0, - SWP_NOREDRAW | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSIZE)); - } - - if (!impl->position_info.mapped && new_info.mapped && GDK_WINDOW_IS_MAPPED (obj)) - ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNA); - - if (impl->position_info.no_bg) - gdk_window_tmp_reset_bg (window); - - impl->position_info = new_info; - - if (new_clip_region) - gdk_window_post_scroll (window, new_clip_region); - - tmp_list = obj->children; - while (tmp_list) - { - gdk_window_postmove (tmp_list->data, &this_pos, anti_scroll); - tmp_list = tmp_list->next; - } -} - -gboolean -_gdk_windowing_window_queue_antiexpose (GdkWindow *window, - GdkRegion *area) -{ - HRGN hrgn = _gdk_win32_gdkregion_to_hrgn (area, 0, 0); - - GDK_NOTE (EVENTS, g_print ("_gdk_windowing_window_queue_antiexpose: ValidateRgn %p %s\n", - GDK_WINDOW_HWND (window), - _gdk_win32_gdkregion_to_string (area))); - - ValidateRgn (GDK_WINDOW_HWND (window), hrgn); - - DeleteObject (hrgn); - - return FALSE; + //_gdk_win32_window_tmp_reset_parent_bg (window); + _gdk_win32_window_tmp_reset_bg (window, TRUE); } void -_gdk_window_process_expose (GdkWindow *window, - GdkRegion *invalidate_region) +_gdk_win32_window_tmp_unset_bg (GdkWindow *window, + gboolean recurse) { - GdkWindowImplWin32 *impl; - GdkRegion *clip_region; - impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl); - - GDK_NOTE (EVENTS, g_print ("_gdk_window_process_expose: %p %s\n", - GDK_WINDOW_HWND (window), - _gdk_win32_gdkregion_to_string (invalidate_region))); - clip_region = gdk_region_rectangle (&impl->position_info.clip_rect); - gdk_region_intersect (invalidate_region, clip_region); + GdkWindowObject *private; - if (!gdk_region_empty (invalidate_region)) - gdk_window_invalidate_region (window, invalidate_region, FALSE); - - gdk_region_destroy (clip_region); + g_return_if_fail (GDK_IS_WINDOW (window)); + + private = (GdkWindowObject *)window; + + if (private->input_only || private->destroyed || + (private->window_type != GDK_WINDOW_ROOT && + !GDK_WINDOW_IS_MAPPED (window))) + return; + + if (_gdk_window_has_impl (window) && + GDK_WINDOW_IS_WIN32 (window) && + private->window_type != GDK_WINDOW_ROOT && + private->window_type != GDK_WINDOW_FOREIGN) + tmp_unset_bg (window); + + if (recurse) + { + GList *l; + + for (l = private->children; l != NULL; l = l->next) + _gdk_win32_window_tmp_unset_bg (l->data, TRUE); + } } static void -gdk_window_tmp_unset_bg (GdkWindow *window) +tmp_unset_bg (GdkWindow *window) { GdkWindowImplWin32 *impl; GdkWindowObject *obj; @@ -667,18 +153,77 @@ gdk_window_tmp_unset_bg (GdkWindow *window) obj = (GdkWindowObject *) window; impl = GDK_WINDOW_IMPL_WIN32 (obj->impl); - impl->position_info.no_bg = TRUE; + impl->no_bg = TRUE; /* * The X version sets background = None to avoid updateing for a moment. * Not sure if this could really emulate it. */ if (obj->bg_pixmap != GDK_NO_BG) - /* handled in WM_ERASEBKGRND proceesing */; + { + ///* handled in WM_ERASEBKGRND proceesing */; + + //HDC hdc = GetDC (GDK_WINDOW_HWND (window)); + //erase_background (window, hdc); + } } static void -gdk_window_tmp_reset_bg (GdkWindow *window) +tmp_reset_bg (GdkWindow *window) +{ + GdkWindowObject *obj; + GdkWindowImplWin32 *impl; + + obj = GDK_WINDOW_OBJECT (window); + impl = GDK_WINDOW_IMPL_WIN32 (obj->impl); + + impl->no_bg = FALSE; +} + +void +_gdk_win32_window_tmp_unset_parent_bg (GdkWindow *window) +{ + GdkWindowObject *private = (GdkWindowObject*)window; + + if (GDK_WINDOW_TYPE (private->parent) == GDK_WINDOW_ROOT) + return; + + window = _gdk_window_get_impl_window ((GdkWindow*)private->parent); + _gdk_win32_window_tmp_unset_bg (window, FALSE); +} + +void +_gdk_win32_window_tmp_reset_bg (GdkWindow *window, + gboolean recurse) +{ + GdkWindowObject *private = (GdkWindowObject*)window; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + if (private->input_only || private->destroyed || + (private->window_type != GDK_WINDOW_ROOT && !GDK_WINDOW_IS_MAPPED (window))) + return; + + if (_gdk_window_has_impl (window) && + GDK_WINDOW_IS_WIN32 (window) && + private->window_type != GDK_WINDOW_ROOT && + private->window_type != GDK_WINDOW_FOREIGN) + { + tmp_reset_bg (window); + } + + if (recurse) + { + GList *l; + + for (l = private->children; l != NULL; l = l->next) + _gdk_win32_window_tmp_reset_bg (l->data, TRUE); + } +} + +/* +void +_gdk_win32_window_tmp_reset_bg (GdkWindow *window) { GdkWindowImplWin32 *impl; GdkWindowObject *obj; @@ -686,9 +231,11 @@ gdk_window_tmp_reset_bg (GdkWindow *window) obj = (GdkWindowObject *) window; impl = GDK_WINDOW_IMPL_WIN32 (obj->impl); - impl->position_info.no_bg = FALSE; + impl->no_bg = FALSE; } +*/ +#if 0 static GdkRegion * gdk_window_clip_changed (GdkWindow *window, GdkRectangle *old_clip, @@ -723,11 +270,14 @@ gdk_window_clip_changed (GdkWindow *window, gdk_region_destroy (new_clip_region); new_clip_region = NULL; } + gdk_region_destroy (old_clip_region); return new_clip_region; } +#endif +#if 0 static void gdk_window_post_scroll (GdkWindow *window, GdkRegion *new_clip_region) @@ -737,5 +287,8 @@ gdk_window_post_scroll (GdkWindow *window, _gdk_win32_gdkregion_to_string (new_clip_region))); gdk_window_invalidate_region (window, new_clip_region, FALSE); + g_print ("gdk_window_post_scroll\n"); gdk_region_destroy (new_clip_region); } + +#endif diff --git a/gdk/win32/gdkimage-win32.c b/gdk/win32/gdkimage-win32.c index 9a5aaf582c..4359183b9b 100644 --- a/gdk/win32/gdkimage-win32.c +++ b/gdk/win32/gdkimage-win32.c @@ -266,7 +266,7 @@ _gdk_win32_copy_to_image (GdkDrawable *drawable, (FALSE, GDK_DRAWABLE_IMPL_WIN32 (GDK_PIXMAP_OBJECT (image->windowing_data)->impl), gc, drawable, src_x, src_y, dest_x, dest_y, width, height); - gdk_gc_unref (gc); + g_object_unref (gc); return image; } @@ -392,7 +392,7 @@ gdk_win32_image_destroy (GdkImage *image) GDK_NOTE (IMAGE, g_print ("gdk_win32_image_destroy: %p\n", GDK_PIXMAP_HBITMAP (pixmap))); - gdk_pixmap_unref (pixmap); + g_object_unref (pixmap); image->windowing_data = NULL; } diff --git a/gdk/win32/gdkinput-win32.c b/gdk/win32/gdkinput-win32.c index d844a5832f..1510c24b4c 100644 --- a/gdk/win32/gdkinput-win32.c +++ b/gdk/win32/gdkinput-win32.c @@ -647,7 +647,8 @@ gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev, gdouble *x_out, gdouble *y_out) { - GdkWindowImplWin32 *impl, *root_impl; + GdkWindowImplWin32 *root_impl; + GdkWindowObject *window_object; int i; int x_axis = 0; @@ -656,33 +657,31 @@ gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev, double device_width, device_height; double x_offset, y_offset, x_scale, y_scale; - impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (input_window->window)->impl); + window_object = GDK_WINDOW_OBJECT (input_window); for (i=0; iinfo.num_axes; i++) { switch (gdkdev->info.axes[i].use) - { - case GDK_AXIS_X: - x_axis = i; - break; - case GDK_AXIS_Y: - y_axis = i; - break; - default: - break; - } + { + case GDK_AXIS_X: + x_axis = i; + break; + case GDK_AXIS_Y: + y_axis = i; + break; + default: + break; + } } - device_width = gdkdev->axes[x_axis].max_value - - gdkdev->axes[x_axis].min_value; - device_height = gdkdev->axes[y_axis].max_value - - gdkdev->axes[y_axis].min_value; + device_width = gdkdev->axes[x_axis].max_value - gdkdev->axes[x_axis].min_value; + device_height = gdkdev->axes[y_axis].max_value - gdkdev->axes[y_axis].min_value; if (gdkdev->info.mode == GDK_MODE_SCREEN) { root_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (_gdk_root)->impl); - x_scale = root_impl->width / device_width; - y_scale = root_impl->height / device_height; + x_scale = GDK_WINDOW_OBJECT (_gdk_root)->width / device_width; + y_scale = GDK_WINDOW_OBJECT (_gdk_root)->height / device_height; x_offset = - input_window->root_x; y_offset = - input_window->root_y; @@ -692,50 +691,48 @@ gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev, double device_aspect = (device_height*gdkdev->axes[y_axis].resolution) / (device_width*gdkdev->axes[x_axis].resolution); - if (device_aspect * impl->width >= impl->height) - { - /* device taller than window */ - x_scale = impl->width / device_width; - y_scale = (x_scale * gdkdev->axes[x_axis].resolution) - / gdkdev->axes[y_axis].resolution; + if (device_aspect * window_object->width >= window_object->height) + { + /* device taller than window */ + x_scale = window_object->width / device_width; + y_scale = (x_scale * gdkdev->axes[x_axis].resolution) / gdkdev->axes[y_axis].resolution; - x_offset = 0; - y_offset = -(device_height * y_scale - - impl->height)/2; - } + x_offset = 0; + y_offset = -(device_height * y_scale - window_object->height) / 2; + } else - { - /* window taller than device */ - y_scale = impl->height / device_height; - x_scale = (y_scale * gdkdev->axes[y_axis].resolution) - / gdkdev->axes[x_axis].resolution; + { + /* window taller than device */ + y_scale = window_object->height / device_height; + x_scale = (y_scale * gdkdev->axes[y_axis].resolution) + / gdkdev->axes[x_axis].resolution; - y_offset = 0; - x_offset = - (device_width * x_scale - impl->width)/2; - } + y_offset = 0; + x_offset = - (device_width * x_scale - window_object->width) / 2; + } } - for (i=0; iinfo.num_axes; i++) + for (i = 0; i < gdkdev->info.num_axes; i++) { switch (gdkdev->info.axes[i].use) - { - case GDK_AXIS_X: - axis_out[i] = x_offset + x_scale*axis_data[x_axis]; - if (x_out) - *x_out = axis_out[i]; - break; - case GDK_AXIS_Y: - axis_out[i] = y_offset + y_scale*axis_data[y_axis]; - if (y_out) - *y_out = axis_out[i]; - break; - default: - axis_out[i] = - (gdkdev->info.axes[i].max * (axis_data[i] - gdkdev->axes[i].min_value) + - gdkdev->info.axes[i].min * (gdkdev->axes[i].max_value - axis_data[i])) / - (gdkdev->axes[i].max_value - gdkdev->axes[i].min_value); - break; - } + { + case GDK_AXIS_X: + axis_out[i] = x_offset + x_scale * axis_data[x_axis]; + if (x_out) + *x_out = axis_out[i]; + break; + case GDK_AXIS_Y: + axis_out[i] = y_offset + y_scale * axis_data[y_axis]; + if (y_out) + *y_out = axis_out[i]; + break; + default: + axis_out[i] = + (gdkdev->info.axes[i].max * (axis_data[i] - gdkdev->axes[i].min_value) + + gdkdev->info.axes[i].min * (gdkdev->axes[i].max_value - axis_data[i])) / + (gdkdev->axes[i].max_value - gdkdev->axes[i].min_value); + break; + } } } diff --git a/gdk/win32/gdkinput-win32.h b/gdk/win32/gdkinput-win32.h index 1f402adad8..608d8f99d6 100644 --- a/gdk/win32/gdkinput-win32.h +++ b/gdk/win32/gdkinput-win32.h @@ -32,7 +32,6 @@ typedef struct _GdkAxisInfo GdkAxisInfo; typedef struct _GdkDevicePrivate GdkDevicePrivate; -typedef struct _GdkInputWindow GdkInputWindow; /* information about a device axis */ struct _GdkAxisInfo @@ -109,12 +108,16 @@ GdkTimeCoord ** _gdk_device_allocate_history (GdkDevice *device, /* The following functions are provided by each implementation * (just wintab for now) */ -void _gdk_input_configure_event (GdkWindow *window); -void _gdk_input_enter_event (GdkWindow *window); +void _gdk_input_configure_event (GdkWindow *window); +void _gdk_input_enter_event (GdkWindow *window); gboolean _gdk_input_other_event (GdkEvent *event, MSG *msg, GdkWindow *window); +void _gdk_input_crossing_event (GdkWindow *window, + gboolean enter); + + /* These should be in gdkinternals.h */ GdkInputWindow *_gdk_input_window_find (GdkWindow *window); diff --git a/gdk/win32/gdkinput.c b/gdk/win32/gdkinput.c index 477f4e3831..ddf1d91e7f 100644 --- a/gdk/win32/gdkinput.c +++ b/gdk/win32/gdkinput.c @@ -310,6 +310,34 @@ _gdk_input_window_destroy (GdkWindow *window) g_free(input_window); } +void +_gdk_input_crossing_event (GdkWindow *window, + gboolean enter) +{ + GdkWindowObject *priv = (GdkWindowObject *)window; + GdkInputWindow *input_window; + gint root_x, root_y; + + if (enter) + { +#if 0 + /* No idea what to do... */ +#if 0 + gdk_input_check_proximity(display); +#endif + input_window = priv->input_window; + if (input_window != NULL) + { + _gdk_input_get_root_relative_geometry (window, &root_x, &root_y); + input_window->root_x = root_x; + input_window->root_y = root_y; + } +#endif + } + else + _gdk_input_ignore_core = FALSE; +} + void _gdk_input_exit (void) { diff --git a/gdk/win32/gdkmain-win32.c b/gdk/win32/gdkmain-win32.c index 4d6e0de648..ee0b5574db 100644 --- a/gdk/win32/gdkmain-win32.c +++ b/gdk/win32/gdkmain-win32.c @@ -149,13 +149,15 @@ gdk_get_use_xshm (void) gint gdk_screen_get_width (GdkScreen *screen) { - return GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (_gdk_root)->impl)->width; + //return GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (_gdk_root)->impl)->width; + return GDK_WINDOW_OBJECT (_gdk_root)->width; } gint gdk_screen_get_height (GdkScreen *screen) { - return GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (_gdk_root)->impl)->height; + //return GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (_gdk_root)->impl)->height; + return GDK_WINDOW_OBJECT (_gdk_root)->height; } gint gdk_screen_get_width_mm (GdkScreen *screen) @@ -621,6 +623,9 @@ _gdk_win32_window_exstyle_to_string (LONG style) BIT (ACCEPTFILES); BIT (APPWINDOW); BIT (CLIENTEDGE); +#ifndef WS_EX_COMPOSITED +# define WS_EX_COMPOSITED 0x02000000L +#endif BIT (COMPOSITED); BIT (CONTEXTHELP); BIT (CONTROLPARENT); @@ -1163,6 +1168,8 @@ _gdk_win32_drawable_description (GdkDrawable *d) { gint width, height, depth; + g_return_val_if_fail (GDK_IS_DRAWABLE (d), NULL); + gdk_drawable_get_size (d, &width, &height); depth = gdk_drawable_get_depth (d); diff --git a/gdk/win32/gdkpixmap-win32.c b/gdk/win32/gdkpixmap-win32.c index 911fa9ddbc..d231cbd106 100644 --- a/gdk/win32/gdkpixmap-win32.c +++ b/gdk/win32/gdkpixmap-win32.c @@ -130,7 +130,7 @@ gdk_pixmap_impl_win32_get_size (GdkDrawable *drawable, } GdkPixmap* -gdk_pixmap_new (GdkDrawable *drawable, +_gdk_pixmap_new (GdkDrawable *drawable, gint width, gint height, gint depth) @@ -348,7 +348,7 @@ static const unsigned char mirror[256] = { }; GdkPixmap * -gdk_bitmap_create_from_data (GdkDrawable *drawable, +_gdk_bitmap_create_from_data (GdkDrawable *drawable, const gchar *data, gint width, gint height) @@ -388,7 +388,7 @@ gdk_bitmap_create_from_data (GdkDrawable *drawable, } GdkPixmap* -gdk_pixmap_create_from_data (GdkDrawable *drawable, +_gdk_pixmap_create_from_data (GdkDrawable *drawable, const gchar *data, gint width, gint height, @@ -428,7 +428,7 @@ gdk_pixmap_create_from_data (GdkDrawable *drawable, GDK_DRAWABLE_IMPL_WIN32 (GDK_PIXMAP_OBJECT (result)->impl), gc, source, 0, 0, 0, 0, width, height); g_object_unref (source); - gdk_gc_unref (gc); + g_object_unref (gc); GDK_NOTE (PIXMAP, g_print ("gdk_pixmap_create_from_data: %dx%dx%d=%p\n", width, height, depth, diff --git a/gdk/win32/gdkprivate-win32.h b/gdk/win32/gdkprivate-win32.h index 810a28a7aa..a2f653c6bf 100644 --- a/gdk/win32/gdkprivate-win32.h +++ b/gdk/win32/gdkprivate-win32.h @@ -112,6 +112,11 @@ #define GDK_IS_GC_WIN32_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_GC_WIN32)) #define GDK_GC_WIN32_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_GC_WIN32, GdkGCWin32Class)) +//#define GDK_WINDOW_SCREEN(win) (_gdk_screen) +GdkScreen *GDK_WINDOW_SCREEN(GObject *win); + +#define GDK_WINDOW_IS_WIN32(win) (GDK_IS_WINDOW_IMPL_WIN32 (((GdkWindowObject *)win)->impl)) + typedef struct _GdkColormapPrivateWin32 GdkColormapPrivateWin32; typedef struct _GdkCursorPrivate GdkCursorPrivate; typedef struct _GdkWin32SingleFont GdkWin32SingleFont; @@ -133,6 +138,8 @@ struct _GdkWin32SingleFont FONTSIGNATURE fs; }; +#ifndef GDK_DISABLE_DEPRECATED + struct _GdkFontPrivateWin32 { GdkFontPrivate base; @@ -140,6 +147,8 @@ struct _GdkFontPrivateWin32 GSList *names; }; +#endif /* GDK_DISABLE_DEPRECATED */ + struct _GdkVisualClass { GObjectClass parent_class; @@ -229,9 +238,6 @@ void _gdk_win32_windowing_window_get_offsets (GdkWindow *window, gint *y_offset); -void _gdk_window_process_expose (GdkWindow *window, - GdkRegion *invalidate_region); - void _gdk_win32_selection_init (void); void _gdk_win32_dnd_exit (void); @@ -455,7 +461,7 @@ HICON _gdk_win32_pixbuf_to_hcursor (GdkPixbuf *pixbuf, gboolean _gdk_win32_pixbuf_to_hicon_supports_alpha (void); /* Initialization */ -void _gdk_windowing_window_init (void); +void _gdk_windowing_window_init (GdkScreen *screen); void _gdk_root_window_size_init (void); void _gdk_monitor_init(void); void _gdk_visual_init (void); diff --git a/gdk/win32/gdkwindow-win32.c b/gdk/win32/gdkwindow-win32.c index 340cc2a063..e472b914c5 100644 --- a/gdk/win32/gdkwindow-win32.c +++ b/gdk/win32/gdkwindow-win32.c @@ -1,8 +1,8 @@ /* GDK - The GIMP Drawing Kit * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald * Copyright (C) 1998-2004 Tor Lillqvist - * Copyright (C) 2001-2004 Hans Breuer - * Copyright (C) 2007 Cody Russell + * Copyright (C) 2001-2009 Hans Breuer + * Copyright (C) 2007-2009 Cody Russell * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -39,10 +39,6 @@ static GdkColormap* gdk_window_impl_win32_get_colormap (GdkDrawable *drawable); static void gdk_window_impl_win32_set_colormap (GdkDrawable *drawable, GdkColormap *cmap); -static void gdk_window_impl_win32_get_size (GdkDrawable *drawable, - gint *width, - gint *height); -static GdkRegion* gdk_window_impl_win32_get_visible_region (GdkDrawable *drawable); static void gdk_window_impl_win32_init (GdkWindowImplWin32 *window); static void gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass); static void gdk_window_impl_win32_finalize (GObject *object); @@ -56,10 +52,17 @@ static gboolean _gdk_window_get_functions (GdkWindow *window, #define WINDOW_IS_TOPLEVEL(window) \ (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \ - GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN) + GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN && \ + GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN) static void gdk_window_impl_iface_init (GdkWindowImplIface *iface); +GdkScreen * +GDK_WINDOW_SCREEN (GObject *win) +{ + return _gdk_screen; +} + GType _gdk_window_impl_win32_get_type (void) { @@ -107,8 +110,6 @@ _gdk_window_impl_get_type (void) static void gdk_window_impl_win32_init (GdkWindowImplWin32 *impl) { - impl->width = 1; - impl->height = 1; impl->toplevel_window_type = -1; impl->hcursor = NULL; impl->hicon_big = NULL; @@ -134,11 +135,6 @@ gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass) drawable_class->set_colormap = gdk_window_impl_win32_set_colormap; drawable_class->get_colormap = gdk_window_impl_win32_get_colormap; - drawable_class->get_size = gdk_window_impl_win32_get_size; - - /* Visible and clip regions are the same */ - drawable_class->get_clip_region = gdk_window_impl_win32_get_visible_region; - drawable_class->get_visible_region = gdk_window_impl_win32_get_visible_region; } static void @@ -236,53 +232,24 @@ gdk_window_impl_win32_set_colormap (GdkDrawable *drawable, } } -static void -gdk_window_impl_win32_get_size (GdkDrawable *drawable, - gint *width, - gint *height) -{ - g_return_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (drawable)); - - if (width) - *width = GDK_WINDOW_IMPL_WIN32 (drawable)->width; - if (height) - *height = GDK_WINDOW_IMPL_WIN32 (drawable)->height; -} - -static GdkRegion* -gdk_window_impl_win32_get_visible_region (GdkDrawable *drawable) -{ - GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (drawable); - GdkRectangle result_rect; - - result_rect.x = 0; - result_rect.y = 0; - result_rect.width = impl->width; - result_rect.height = impl->height; - - gdk_rectangle_intersect (&result_rect, &impl->position_info.clip_rect, &result_rect); - - return gdk_region_rectangle (&result_rect); -} - void _gdk_root_window_size_init (void) { - GdkWindowImplWin32 *impl; + GdkWindowObject *window_object; GdkRectangle rect; int i; - impl = GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) _gdk_root)->impl); + window_object = GDK_WINDOW_OBJECT (_gdk_root); rect = _gdk_monitors[0].rect; for (i = 1; i < _gdk_num_monitors; i++) gdk_rectangle_union (&rect, &_gdk_monitors[i].rect, &rect); - impl->width = rect.width; - impl->height = rect.height; + window_object->width = rect.width; + window_object->height = rect.height; } void -_gdk_windowing_window_init (void) +_gdk_windowing_window_init (GdkScreen *screen) { GdkWindowObject *private; GdkDrawableImplWin32 *draw_impl; @@ -292,6 +259,8 @@ _gdk_windowing_window_init (void) _gdk_root = g_object_new (GDK_TYPE_WINDOW, NULL); private = (GdkWindowObject *)_gdk_root; private->impl = g_object_new (_gdk_window_impl_get_type (), NULL); + private->impl_window = private; + draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl); draw_impl->handle = GetDesktopWindow (); @@ -303,8 +272,14 @@ _gdk_windowing_window_init (void) private->depth = gdk_visual_get_system ()->depth; _gdk_root_window_size_init (); - - _gdk_window_init_position (GDK_WINDOW (private)); + + private->x = 0; + private->y = 0; + private->abs_x = 0; + private->abs_y = 0; + private->width = GetSystemMetrics (SM_CXSCREEN); + private->height = GetSystemMetrics (SM_CYSCREEN); + private->viewable = TRUE; gdk_win32_handle_table_insert ((HANDLE *) &draw_impl->handle, _gdk_root); @@ -486,102 +461,64 @@ RegisterGdkClass (GdkWindowType wtype, GdkWindowTypeHint wtype_hint) return klass; } -static GdkWindow* -gdk_window_new_internal (GdkWindow *parent, - GdkWindowAttr *attributes, - gint attributes_mask, - gboolean from_set_skip_taskbar_hint) +void +_gdk_window_impl_new (GdkWindow *window, + GdkWindow *real_parent, + GdkScreen *screen, + GdkVisual *visual, + GdkEventMask event_mask, + GdkWindowAttr *attributes, + gint attributes_mask) { HWND hwndNew; HANDLE hparent; ATOM klass = 0; DWORD dwStyle = 0, dwExStyle; RECT rect; - GdkWindow *window; GdkWindow *orig_parent; GdkWindowObject *private; GdkWindowImplWin32 *impl; GdkDrawableImplWin32 *draw_impl; - GdkVisual *visual; const gchar *title; wchar_t *wtitle; gint window_width, window_height; gint offset_x = 0, offset_y = 0; - g_return_val_if_fail (attributes != NULL, NULL); + private = (GdkWindowObject *)window; - if (!parent) - parent = _gdk_root; - - g_return_val_if_fail (GDK_IS_WINDOW (parent), NULL); - - orig_parent = parent; + orig_parent = real_parent; GDK_NOTE (MISC, g_print ("gdk_window_new_internal: %s\n", - (attributes->window_type == GDK_WINDOW_TOPLEVEL ? "TOPLEVEL" : - (attributes->window_type == GDK_WINDOW_CHILD ? "CHILD" : - (attributes->window_type == GDK_WINDOW_DIALOG ? "DIALOG" : + (attributes->window_type == GDK_WINDOW_TOPLEVEL ? "TOPLEVEL" : + (attributes->window_type == GDK_WINDOW_CHILD ? "CHILD" : + (attributes->window_type == GDK_WINDOW_DIALOG ? "DIALOG" : (attributes->window_type == GDK_WINDOW_TEMP ? "TEMP" : - "???")))))); + "???")))))); - if (GDK_WINDOW_DESTROYED (parent)) - return NULL; - - hparent = GDK_WINDOW_HWND (parent); + hparent = GDK_WINDOW_HWND (real_parent); - window = g_object_new (GDK_TYPE_WINDOW, NULL); - private = (GdkWindowObject *)window; - private->impl = g_object_new (_gdk_window_impl_get_type (), NULL); - impl = GDK_WINDOW_IMPL_WIN32 (private->impl); - draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl); + impl = g_object_new (_gdk_window_impl_get_type (), NULL); + private->impl = (GdkDrawable *)impl; + draw_impl = GDK_DRAWABLE_IMPL_WIN32 (impl); draw_impl->wrapper = GDK_DRAWABLE (window); - /* Windows with a foreign parent are treated as if they are children - * of the root window, except for actual creation. - */ - if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_FOREIGN) - parent = _gdk_root; - - private->parent = (GdkWindowObject *)parent; + // XXX: xattributes_mask = 0 - private->accept_focus = TRUE; - private->focus_on_map = TRUE; - - if (attributes_mask & GDK_WA_X) - private->x = attributes->x; - else - private->x = 0; - - if (attributes_mask & GDK_WA_Y) - private->y = attributes->y; - else if (attributes_mask & GDK_WA_X) - private->y = 100; /* ??? We must put it somewhere... */ - else - private->y = 0; - +#if 0 if (attributes_mask & GDK_WA_VISUAL) visual = attributes->visual; else visual = gdk_visual_get_system (); +#endif +#if 0 impl->width = (attributes->width > 1) ? (attributes->width) : (1); impl->height = (attributes->height > 1) ? (attributes->height) : (1); +#endif impl->extension_events_selected = FALSE; - if (attributes->wclass == GDK_INPUT_ONLY) - { - /* Backwards compatiblity - we've always ignored - * attributes->window_type for input-only windows - * before - */ - if (parent == _gdk_root) - private->window_type = GDK_WINDOW_TEMP; - else - private->window_type = GDK_WINDOW_CHILD; - } - else - private->window_type = attributes->window_type; + // XXX ? if (attributes->wclass == GDK_INPUT_OUTPUT) { dwExStyle = 0; @@ -592,8 +529,8 @@ gdk_window_new_internal (GdkWindow *parent, if (attributes_mask & GDK_WA_COLORMAP) { draw_impl->colormap = attributes->colormap; - g_object_ref (attributes->colormap); - } + g_object_ref (attributes->colormap); + } else { draw_impl->colormap = gdk_screen_get_system_colormap (_gdk_screen); @@ -618,10 +555,9 @@ gdk_window_new_internal (GdkWindow *parent, { case GDK_WINDOW_TOPLEVEL: case GDK_WINDOW_DIALOG: - if (parent != _gdk_root) + if (GDK_WINDOW_TYPE (private->parent) != GDK_WINDOW_ROOT) { - g_warning (G_STRLOC ": Toplevel windows must be created as children\n" - "of a window of type GDK_WINDOW_ROOT or GDK_WINDOW_FOREIGN"); + /* The common code warns for this case. */ hparent = GetDesktopWindow (); } /* Children of foreign windows aren't toplevel windows */ @@ -647,28 +583,22 @@ gdk_window_new_internal (GdkWindow *parent, case GDK_WINDOW_TEMP: /* A temp window is not necessarily a top level window */ - dwStyle = (_gdk_root == parent ? WS_POPUP : WS_CHILDWINDOW); + dwStyle = (_gdk_root == real_parent ? WS_POPUP : WS_CHILDWINDOW); dwStyle |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS; dwExStyle |= WS_EX_TOOLWINDOW; offset_x = _gdk_offset_x; offset_y = _gdk_offset_y; break; - case GDK_WINDOW_ROOT: - g_error ("cannot make windows of type GDK_WINDOW_ROOT"); - break; - default: g_assert_not_reached (); } - _gdk_window_init_position (GDK_WINDOW (private)); - if (private->window_type != GDK_WINDOW_CHILD) { rect.left = rect.top = 0; - rect.right = impl->position_info.width; - rect.bottom = impl->position_info.height; + rect.right = private->width; + rect.bottom = private->height; AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle); @@ -677,8 +607,8 @@ gdk_window_new_internal (GdkWindow *parent, } else { - window_width = impl->position_info.width; - window_height = impl->position_info.height; + window_width = private->width; + window_height = private->height; } if (attributes_mask & GDK_WA_TITLE) @@ -710,8 +640,8 @@ gdk_window_new_internal (GdkWindow *parent, wtitle, dwStyle, ((attributes_mask & GDK_WA_X) ? - impl->position_info.x - offset_x : CW_USEDEFAULT), - impl->position_info.y - offset_y, + private->x - offset_x : CW_USEDEFAULT), + private->y - offset_y, window_width, window_height, hparent, NULL, @@ -746,8 +676,8 @@ gdk_window_new_internal (GdkWindow *parent, title, window_width, window_height, ((attributes_mask & GDK_WA_X) ? - impl->position_info.x - offset_x: CW_USEDEFAULT), - impl->position_info.y - offset_y, + private->x - offset_x: CW_USEDEFAULT), + private->y - offset_y, hparent, GDK_WINDOW_HWND (window))); @@ -760,25 +690,15 @@ gdk_window_new_internal (GdkWindow *parent, { WIN32_API_FAILED ("CreateWindowExW"); g_object_unref (window); - return NULL; + return; } - if (!from_set_skip_taskbar_hint && private->window_type == GDK_WINDOW_TEMP) - gdk_window_set_skip_taskbar_hint (window, TRUE); +// if (!from_set_skip_taskbar_hint && private->window_type == GDK_WINDOW_TEMP) +// gdk_window_set_skip_taskbar_hint (window, TRUE); gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ? (attributes->cursor) : NULL)); - - return window; -} - -GdkWindow* -_gdk_window_new (GdkWindow *parent, - GdkWindowAttr *attributes, - gint attributes_mask) -{ - return gdk_window_new_internal (parent, attributes, attributes_mask, FALSE); } GdkWindow * @@ -819,8 +739,8 @@ gdk_window_foreign_new_for_display (GdkDisplay *display, ScreenToClient (parent, &point); private->x = point.x; private->y = point.y; - impl->width = rect.right - rect.left; - impl->height = rect.bottom - rect.top; + private->width = rect.right - rect.left; + private->height = rect.bottom - rect.top; private->window_type = GDK_WINDOW_FOREIGN; private->destroyed = FALSE; private->event_mask = GDK_ALL_EVENTS_MASK; /* XXX */ @@ -833,11 +753,10 @@ gdk_window_foreign_new_for_display (GdkDisplay *display, else private->state &= (~GDK_WINDOW_STATE_ABOVE); private->state &= (~GDK_WINDOW_STATE_BELOW); + private->viewable = TRUE; private->depth = gdk_visual_get_system ()->depth; - _gdk_window_init_position (GDK_WINDOW (private)); - g_object_ref (window); gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window); @@ -856,9 +775,9 @@ gdk_window_lookup (GdkNativeWindow hwnd) } void -_gdk_windowing_window_destroy (GdkWindow *window, - gboolean recursing, - gboolean foreign_destroy) +_gdk_win32_window_destroy (GdkWindow *window, + gboolean recursing, + gboolean foreign_destroy) { GdkWindowObject *private = (GdkWindowObject *)window; GdkWindowImplWin32 *window_impl = GDK_WINDOW_IMPL_WIN32 (private->impl); @@ -956,11 +875,17 @@ get_outer_rect (GdkWindow *window, } static void -adjust_for_gravity_hints (GdkWindowImplWin32 *impl, - RECT *outer_rect, - gint *x, - gint *y) +adjust_for_gravity_hints (GdkWindow *window, + RECT *outer_rect, + gint *x, + gint *y) { + GdkWindowObject *obj; + GdkWindowImplWin32 *impl; + + obj = GDK_WINDOW_OBJECT (window); + impl = GDK_WINDOW_IMPL_WIN32 (obj->impl); + if (impl->hint_flags & GDK_HINT_WIN_GRAVITY) { gint orig_x = *x, orig_y = *y; @@ -971,14 +896,14 @@ adjust_for_gravity_hints (GdkWindowImplWin32 *impl, case GDK_GRAVITY_CENTER: case GDK_GRAVITY_SOUTH: *x -= (outer_rect->right - outer_rect->left) / 2; - *x += impl->width / 2; + *x += obj->width / 2; break; case GDK_GRAVITY_SOUTH_EAST: case GDK_GRAVITY_EAST: case GDK_GRAVITY_NORTH_EAST: *x -= outer_rect->right - outer_rect->left; - *x += impl->width; + *x += obj->width; break; case GDK_GRAVITY_STATIC: @@ -995,14 +920,14 @@ adjust_for_gravity_hints (GdkWindowImplWin32 *impl, case GDK_GRAVITY_CENTER: case GDK_GRAVITY_EAST: *y -= (outer_rect->bottom - outer_rect->top) / 2; - *y += impl->height / 2; + *y += obj->height / 2; break; case GDK_GRAVITY_SOUTH_WEST: case GDK_GRAVITY_SOUTH: case GDK_GRAVITY_SOUTH_EAST: *y -= outer_rect->bottom - outer_rect->top; - *y += impl->height; + *y += obj->height; break; case GDK_GRAVITY_STATIC: @@ -1169,9 +1094,10 @@ show_window_internal (GdkWindow *window, } static void -gdk_win32_window_show (GdkWindow *window, gboolean raise) +gdk_win32_window_show (GdkWindow *window, + gboolean already_mapped) { - show_window_internal (window, raise, FALSE); + show_window_internal (window, FALSE, FALSE); } static void @@ -1251,15 +1177,15 @@ gdk_win32_window_move (GdkWindow *window, */ if (GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) != GetDesktopWindow ()) { - _gdk_window_move_resize_child (window, x, y, impl->width, impl->height); + _gdk_window_move_resize_child (window, x, y, private->width, private->height); } else { RECT outer_rect; - get_outer_rect (window, impl->width, impl->height, &outer_rect); + get_outer_rect (window, private->width, private->height, &outer_rect); - adjust_for_gravity_hints (impl, &outer_rect, &x, &y); + adjust_for_gravity_hints (window, &outer_rect, &x, &y); GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,%d,%d,0,0," "NOACTIVATE|NOSIZE|NOZORDER)\n", @@ -1329,7 +1255,7 @@ gdk_win32_window_move_resize_internal (GdkWindow *window, gint width, gint height) { - GdkWindowObject *private = (GdkWindowObject*) window; + GdkWindowObject *private; GdkWindowImplWin32 *impl; g_return_if_fail (GDK_IS_WINDOW (window)); @@ -1342,6 +1268,7 @@ gdk_win32_window_move_resize_internal (GdkWindow *window, if (height < 1) height = 1; + private = GDK_WINDOW_OBJECT (window); impl = GDK_WINDOW_IMPL_WIN32 (private->impl); if (private->state & GDK_WINDOW_STATE_FULLSCREEN) @@ -1361,7 +1288,7 @@ gdk_win32_window_move_resize_internal (GdkWindow *window, get_outer_rect (window, width, height, &outer_rect); - adjust_for_gravity_hints (impl, &outer_rect, &x, &y); + adjust_for_gravity_hints (window, &outer_rect, &x, &y); GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,%d,%d,%ld,%ld," "NOACTIVATE|NOZORDER)\n", @@ -1452,7 +1379,7 @@ gdk_win32_window_reparent (GdkWindow *window, GDK_WINDOW_HWND (new_parent))); API_CALL (MoveWindow, (GDK_WINDOW_HWND (window), - x, y, impl->width, impl->height, TRUE)); + x, y, window_private->width, window_private->height, TRUE)); /* From here on, we treat parents of type GDK_WINDOW_FOREIGN like * the root window @@ -1492,196 +1419,10 @@ gdk_win32_window_reparent (GdkWindow *window, g_list_remove (old_parent_private->children, window); parent_private->children = g_list_prepend (parent_private->children, window); - _gdk_window_init_position (GDK_WINDOW (window_private)); return FALSE; } -static void -erase_background (GdkWindow *window, - HDC hdc) -{ - HDC bgdc = NULL; - HBRUSH hbr = NULL; - HPALETTE holdpal = NULL; - RECT rect; - COLORREF bg; - GdkColormap *colormap; - GdkColormapPrivateWin32 *colormap_private; - int x, y; - int x_offset, y_offset; - - if (((GdkWindowObject *) window)->input_only || - ((GdkWindowObject *) window)->bg_pixmap == GDK_NO_BG || - GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->position_info.no_bg) - { - return; - } - - colormap = gdk_drawable_get_colormap (window); - - if (colormap && - (colormap->visual->type == GDK_VISUAL_PSEUDO_COLOR || - colormap->visual->type == GDK_VISUAL_STATIC_COLOR)) - { - int k; - - colormap_private = GDK_WIN32_COLORMAP_DATA (colormap); - - if (!(holdpal = SelectPalette (hdc, colormap_private->hpal, FALSE))) - WIN32_GDI_FAILED ("SelectPalette"); - else if ((k = RealizePalette (hdc)) == GDI_ERROR) - WIN32_GDI_FAILED ("RealizePalette"); - else if (k > 0) - GDK_NOTE (COLORMAP, g_print ("erase_background: realized %p: %d colors\n", - colormap_private->hpal, k)); - } - - x_offset = y_offset = 0; - while (window && ((GdkWindowObject *) window)->bg_pixmap == GDK_PARENT_RELATIVE_BG) - { - /* If this window should have the same background as the parent, - * fetch the parent. (And if the same goes for the parent, fetch - * the grandparent, etc.) - */ - x_offset += ((GdkWindowObject *) window)->x; - y_offset += ((GdkWindowObject *) window)->y; - window = GDK_WINDOW (((GdkWindowObject *) window)->parent); - } - - if (GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->position_info.no_bg) - { - /* Improves scolling effect, e.g. main buttons of testgtk */ - return; - } - - GetClipBox (hdc, &rect); - - if (((GdkWindowObject *) window)->bg_pixmap == NULL) - { - bg = _gdk_win32_colormap_color (GDK_DRAWABLE_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->colormap, - ((GdkWindowObject *) window)->bg_color.pixel); - - if (!(hbr = CreateSolidBrush (bg))) - WIN32_GDI_FAILED ("CreateSolidBrush"); - else if (!FillRect (hdc, &rect, hbr)) - WIN32_GDI_FAILED ("FillRect"); - if (hbr != NULL) - DeleteObject (hbr); - } - else if (((GdkWindowObject *) window)->bg_pixmap != GDK_NO_BG) - { - GdkPixmap *pixmap = ((GdkWindowObject *) window)->bg_pixmap; - GdkPixmapImplWin32 *pixmap_impl = GDK_PIXMAP_IMPL_WIN32 (GDK_PIXMAP_OBJECT (pixmap)->impl); - - if (x_offset == 0 && y_offset == 0 && - pixmap_impl->width <= 8 && pixmap_impl->height <= 8) - { - if (!(hbr = CreatePatternBrush (GDK_PIXMAP_HBITMAP (pixmap)))) - WIN32_GDI_FAILED ("CreatePatternBrush"); - else if (!FillRect (hdc, &rect, hbr)) - WIN32_GDI_FAILED ("FillRect"); - if (hbr != NULL) - DeleteObject (hbr); - } - else - { - HGDIOBJ oldbitmap; - - if (!(bgdc = CreateCompatibleDC (hdc))) - { - WIN32_GDI_FAILED ("CreateCompatibleDC"); - return; - } - if (!(oldbitmap = SelectObject (bgdc, GDK_PIXMAP_HBITMAP (pixmap)))) - { - WIN32_GDI_FAILED ("SelectObject"); - DeleteDC (bgdc); - return; - } - x = -x_offset; - while (x < rect.right) - { - if (x + pixmap_impl->width >= rect.left) - { - y = -y_offset; - while (y < rect.bottom) - { - if (y + pixmap_impl->height >= rect.top) - { - if (!BitBlt (hdc, x, y, - pixmap_impl->width, pixmap_impl->height, - bgdc, 0, 0, SRCCOPY)) - { - WIN32_GDI_FAILED ("BitBlt"); - SelectObject (bgdc, oldbitmap); - DeleteDC (bgdc); - return; - } - } - y += pixmap_impl->height; - } - } - x += pixmap_impl->width; - } - SelectObject (bgdc, oldbitmap); - DeleteDC (bgdc); - } - } -} - -static void -gdk_win32_window_clear_area (GdkWindow *window, - gint x, - gint y, - gint width, - gint height, - gboolean send_expose) -{ - GdkWindowImplWin32 *impl; - - impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl); - - if (!GDK_WINDOW_DESTROYED (window)) - { - HDC hdc; - RECT rect; - - hdc = GetDC (GDK_WINDOW_HWND (window)); - - if (!send_expose) - { - if (width == 0) - width = impl->width - x; - if (height == 0) - height = impl->height - y; - GDK_NOTE (MISC, g_print ("_gdk_windowing_window_clear_area: %p: " - "%dx%d@%+d%+d\n", - GDK_WINDOW_HWND (window), - width, height, x, y)); - IntersectClipRect (hdc, x, y, x + width, y + height); - erase_background (window, hdc); - GDI_CALL (ReleaseDC, (GDK_WINDOW_HWND (window), hdc)); - } - else - { - /* The background should be erased before the expose event is - generated */ - IntersectClipRect (hdc, x, y, x + width, y + height); - erase_background (window, hdc); - GDI_CALL (ReleaseDC, (GDK_WINDOW_HWND (window), hdc)); - - rect.left = x; - rect.right = x + width; - rect.top = y; - rect.bottom = y + height; - - GDI_CALL (InvalidateRect, (GDK_WINDOW_HWND (window), &rect, TRUE)); - UpdateWindow (GDK_WINDOW_HWND (window)); - } - } -} - static void gdk_win32_window_raise (GdkWindow *window) { @@ -2125,51 +1866,15 @@ gdk_win32_window_set_background (GdkWindow *window, _gdk_win32_color_to_string (color))); private->bg_color = *color; - - if (private->bg_pixmap && - private->bg_pixmap != GDK_PARENT_RELATIVE_BG && - private->bg_pixmap != GDK_NO_BG) - { - g_object_unref (private->bg_pixmap); - private->bg_pixmap = NULL; - } } static void gdk_win32_window_set_back_pixmap (GdkWindow *window, - GdkPixmap *pixmap, - gint parent_relative) + GdkPixmap *pixmap) { GdkWindowObject *private = (GdkWindowObject *)window; - if (pixmap && !gdk_drawable_get_colormap (pixmap)) - { - g_warning ("gdk_window_set_back_pixmap(): pixmap must have a colormap"); - return; - } - - if (private->bg_pixmap && - private->bg_pixmap != GDK_PARENT_RELATIVE_BG && - private->bg_pixmap != GDK_NO_BG) - g_object_unref (private->bg_pixmap); - - if (parent_relative) - { - private->bg_pixmap = GDK_PARENT_RELATIVE_BG; - GDK_NOTE (MISC, g_print (G_STRLOC ": setting background pixmap to parent_relative\n")); - } - else - { - if (pixmap) - { - g_object_ref (pixmap); - private->bg_pixmap = pixmap; - } - else - { - private->bg_pixmap = GDK_NO_BG; - } - } + /* TODO_CSW? but win32 has no XSetWindowBackgroundPixmap */ } static void @@ -2223,7 +1928,8 @@ gdk_win32_window_set_cursor (GdkWindow *window, { /* If the pointer is over our window, set new cursor */ GdkWindow *curr_window = gdk_window_get_pointer (window, NULL, NULL, NULL); - if (curr_window == window) + if (curr_window == window || + (curr_window && window == gdk_window_get_toplevel (curr_window))) SetCursor (impl->hcursor); else { @@ -2343,45 +2049,55 @@ gdk_win32_window_get_geometry (GdkWindow *window, } static gint -gdk_win32_window_get_origin (GdkWindow *window, - gint *x, - gint *y) +gdk_win32_window_get_root_coords (GdkWindow *window, + gint x, + gint y, + gint *root_x, + gint *root_y) { - gint return_val; - gint tx = 0; - gint ty = 0; + gint tx; + gint ty; + POINT pt; - if (!GDK_WINDOW_DESTROYED (window)) - { - POINT pt; - - pt.x = 0; - pt.y = 0; - ClientToScreen (GDK_WINDOW_HWND (window), &pt); - tx = pt.x; - ty = pt.y; - return_val = 1; - } - else - return_val = 0; + pt.x = x; + pt.y = y; + ClientToScreen (GDK_WINDOW_HWND (window), &pt); + tx = pt.x; + ty = pt.y; - if (x) - *x = tx + _gdk_offset_x; - if (y) - *y = ty + _gdk_offset_y; + if (root_x) + *root_x = tx + _gdk_offset_x; + if (root_y) + *root_y = ty + _gdk_offset_y; - GDK_NOTE (MISC, g_print ("gdk_window_get_origin: %p: %+d%+d\n", + GDK_NOTE (MISC, g_print ("gdk_window_get_root_coords: %p: %+d%+d %+d%+d\n", GDK_WINDOW_HWND (window), + x, y, tx, ty)); - return return_val; + return 1; } -gboolean -gdk_window_get_deskrelative_origin (GdkWindow *window, - gint *x, - gint *y) +static gboolean +gdk_win32_window_get_deskrelative_origin (GdkWindow *window, + gint *x, + gint *y) { - return gdk_window_get_origin (window, x, y); + return gdk_win32_window_get_root_coords (window, 0, 0, x, y); +} + +static void +gdk_win32_window_restack_under (GdkWindow *window, + GList *native_siblings) +{ + // ### TODO +} + +static void +gdk_win32_window_restack_toplevel (GdkWindow *window, + GdkWindow *sibling, + gboolean above) +{ + // ### TODO } void @@ -2446,24 +2162,50 @@ gdk_window_get_frame_extents (GdkWindow *window, r.left, r.top)); } -GdkWindow* -_gdk_windowing_window_get_pointer (GdkDisplay *display, - GdkWindow *window, - gint *x, - gint *y, - GdkModifierType *mask) + +static GdkModifierType +get_current_mask (void) { - GdkWindow *return_val; - POINT screen_point, point; - HWND hwnd, hwndc; + GdkModifierType mask; BYTE kbd[256]; - g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL); + GetKeyboardState (kbd); + mask = 0; + if (kbd[VK_SHIFT] & 0x80) + mask |= GDK_SHIFT_MASK; + if (kbd[VK_CAPITAL] & 0x80) + mask |= GDK_LOCK_MASK; + if (kbd[VK_CONTROL] & 0x80) + mask |= GDK_CONTROL_MASK; + if (kbd[VK_MENU] & 0x80) + mask |= GDK_MOD1_MASK; + if (kbd[VK_LBUTTON] & 0x80) + mask |= GDK_BUTTON1_MASK; + if (kbd[VK_MBUTTON] & 0x80) + mask |= GDK_BUTTON2_MASK; + if (kbd[VK_RBUTTON] & 0x80) + mask |= GDK_BUTTON3_MASK; + + return mask; +} + +static gboolean +gdk_window_win32_get_pointer (GdkWindow *window, + gint *x, + gint *y, + GdkModifierType *mask) +{ + gboolean return_val; + POINT point; + HWND hwnd, hwndc; + + g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), FALSE); - return_val = NULL; - GetCursorPos (&screen_point); - point = screen_point; - ScreenToClient (GDK_WINDOW_HWND (window), &point); + return_val = TRUE; + + hwnd = GDK_WINDOW_HWND (window); + GetCursorPos (&point); + ScreenToClient (hwnd, &point); *x = point.x; *y = point.y; @@ -2474,45 +2216,12 @@ _gdk_windowing_window_get_pointer (GdkDisplay *display, *y += _gdk_offset_y; } - hwnd = WindowFromPoint (screen_point); - if (hwnd != NULL) - { - gboolean done = FALSE; - - while (!done) - { - point = screen_point; - ScreenToClient (hwnd, &point); - hwndc = ChildWindowFromPoint (hwnd, point); - if (hwndc == NULL) - done = TRUE; - else if (hwndc == hwnd) - done = TRUE; - else - hwnd = hwndc; - } - - return_val = gdk_window_lookup ((GdkNativeWindow) hwnd); - } - else - return_val = NULL; - - GetKeyboardState (kbd); - *mask = 0; - if (kbd[VK_SHIFT] & 0x80) - *mask |= GDK_SHIFT_MASK; - if (kbd[VK_CAPITAL] & 0x80) - *mask |= GDK_LOCK_MASK; - if (kbd[VK_CONTROL] & 0x80) - *mask |= GDK_CONTROL_MASK; - if (kbd[VK_MENU] & 0x80) - *mask |= GDK_MOD1_MASK; - if (kbd[VK_LBUTTON] & 0x80) - *mask |= GDK_BUTTON1_MASK; - if (kbd[VK_MBUTTON] & 0x80) - *mask |= GDK_BUTTON2_MASK; - if (kbd[VK_RBUTTON] & 0x80) - *mask |= GDK_BUTTON3_MASK; + hwndc = ChildWindowFromPoint (hwnd, point); + if (hwndc != NULL && hwndc != hwnd && + !gdk_win32_handle_table_lookup ((GdkNativeWindow) hwndc)) + return_val = FALSE; /* Direct child unknown to gdk */ + + *mask = get_current_mask (); return return_val; } @@ -2524,10 +2233,16 @@ _gdk_windowing_get_pointer (GdkDisplay *display, gint *y, GdkModifierType *mask) { + POINT point; + g_return_if_fail (display == _gdk_display); *screen = _gdk_screen; - _gdk_windowing_window_get_pointer (_gdk_display, _gdk_root, x, y, mask); + GetCursorPos (&point); + *x = point.x + _gdk_offset_x; + *y = point.y + _gdk_offset_y; + + *mask = get_current_mask (); } void @@ -2545,7 +2260,9 @@ gdk_display_warp_pointer (GdkDisplay *display, GdkWindow* _gdk_windowing_window_at_pointer (GdkDisplay *display, gint *win_x, - gint *win_y) + gint *win_y, + GdkModifierType *mask, + gboolean get_toplevel) { GdkWindow *window; POINT point, pointc; @@ -2567,6 +2284,11 @@ _gdk_windowing_window_at_pointer (GdkDisplay *display, ScreenToClient (hwnd, &point); do { + if (get_toplevel && + (window = gdk_win32_handle_table_lookup ((GdkNativeWindow) hwnd)) != NULL && + GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN) + break; + hwndc = ChildWindowFromPoint (hwnd, point); ClientToScreen (hwnd, &point); ScreenToClient (hwndc, &point); @@ -2645,8 +2367,6 @@ gdk_win32_window_shape_combine_mask (GdkWindow *window, GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %p: none\n", GDK_WINDOW_HWND (window))); SetWindowRgn (GDK_WINDOW_HWND (window), NULL, TRUE); - - private->shaped = FALSE; } else { @@ -2660,32 +2380,9 @@ gdk_win32_window_shape_combine_mask (GdkWindow *window, hrgn = _gdk_win32_bitmap_to_hrgn (mask); do_shape_combine_region (window, hrgn, x, y); - - private->shaped = TRUE; } } -void -gdk_window_input_shape_combine_mask (GdkWindow *window, - GdkBitmap *mask, - gint x, - gint y) -{ - g_return_if_fail (GDK_IS_WINDOW (window)); - - /* Not yet implemented - * - * I don't think there is anything in the Win32 API to directly - * support this. And anyway, as we don't currently support RGBA - * windows, it doesn't really matter. - * - * When we do support RGBA, input shape functionality could probably - * be implemented by saving the input shape region in the per-window - * private data, and then simply checking before generating an input - * event whether the event's coordinates are inside the region. - */ -} - void gdk_window_set_override_redirect (GdkWindow *window, gboolean override_redirect) @@ -3195,26 +2892,6 @@ gdk_win32_window_merge_child_shapes (GdkWindow *window) gdk_propagate_shapes (GDK_WINDOW_HWND (window), TRUE); } -void -gdk_window_set_child_input_shapes (GdkWindow *window) -{ - g_return_if_fail (GDK_IS_WINDOW (window)); - - /* Not yet implemented. See comment in - * gdk_window_input_shape_combine_mask(). - */ -} - -void -gdk_window_merge_child_input_shapes (GdkWindow *window) -{ - g_return_if_fail (GDK_IS_WINDOW (window)); - - /* Not yet implemented. See comment in - * gdk_window_input_shape_combine_mask(). - */ -} - static gboolean gdk_win32_window_set_static_gravities (GdkWindow *window, gboolean use_static) @@ -3651,7 +3328,7 @@ gdk_window_set_skip_taskbar_hint (GdkWindow *window, gboolean skips_taskbar) { static GdkWindow *owner = NULL; - GdkWindowAttr wa; + //GdkWindowAttr wa; g_return_if_fail (GDK_IS_WINDOW (window)); @@ -3664,20 +3341,23 @@ gdk_window_set_skip_taskbar_hint (GdkWindow *window, if (skips_taskbar) { +#if 0 if (owner == NULL) - { - wa.window_type = GDK_WINDOW_TEMP; - wa.wclass = GDK_INPUT_OUTPUT; - wa.width = wa.height = 1; - wa.event_mask = 0; - owner = gdk_window_new_internal (NULL, &wa, 0, TRUE); - } + { + wa.window_type = GDK_WINDOW_TEMP; + wa.wclass = GDK_INPUT_OUTPUT; + wa.width = wa.height = 1; + wa.event_mask = 0; + owner = gdk_window_new_internal (NULL, &wa, 0, TRUE); + } +#endif SetWindowLongPtr (GDK_WINDOW_HWND (window), GWLP_HWNDPARENT, (LONG_PTR) GDK_WINDOW_HWND (owner)); #if 0 /* Should we also turn off the minimize and maximize buttons? */ SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE) & ~(WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU)); + SetWindowPos (GDK_WINDOW_HWND (window), NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | @@ -3752,8 +3432,6 @@ gdk_win32_window_shape_combine_region (GdkWindow *window, GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_region: %p: none\n", GDK_WINDOW_HWND (window))); SetWindowRgn (GDK_WINDOW_HWND (window), NULL, TRUE); - - private->shaped = FALSE; } else { @@ -3766,24 +3444,9 @@ gdk_win32_window_shape_combine_region (GdkWindow *window, hrgn)); do_shape_combine_region (window, hrgn, offset_x, offset_y); - - private->shaped = TRUE; } } -void -gdk_window_input_shape_combine_region (GdkWindow *window, - const GdkRegion *shape_region, - gint offset_x, - gint offset_y) -{ - g_return_if_fail (GDK_IS_WINDOW (window)); - - /* Not yet implemented. See comment in - * gdk_window_input_shape_combine_mask(). - */ -} - GdkWindow * gdk_window_lookup_for_display (GdkDisplay *display, GdkNativeWindow anid) @@ -3806,7 +3469,7 @@ gdk_window_configure_finished (GdkWindow *window) } void -gdk_window_beep (GdkWindow *window) +_gdk_windowing_window_beep (GdkWindow *window) { gdk_display_beep (_gdk_display); } @@ -3849,11 +3512,131 @@ gdk_window_set_opacity (GdkWindow *window, } } +GdkRegion * +_gdk_windowing_get_shape_for_mask (GdkBitmap *mask) +{ + GdkRegion *region; + HRGN hrgn = _gdk_win32_bitmap_to_hrgn (mask); + + region = _gdk_win32_hrgn_to_region (hrgn); + DeleteObject (hrgn); + + return region; +} + void _gdk_windowing_window_set_composited (GdkWindow *window, gboolean composited) { } +GdkRegion * +_gdk_windowing_window_get_shape (GdkWindow *window) +{ + HRGN hrgn = CreateRectRgn (0, 0, 0, 0); + int type = GetWindowRgn (GDK_WINDOW_HWND (window), hrgn); + + if (type == SIMPLEREGION || type == COMPLEXREGION) + { + GdkRegion *region = _gdk_win32_hrgn_to_region (hrgn); + + DeleteObject (hrgn); + return region; + } + + return NULL; +} + +GdkRegion * +_gdk_windowing_window_get_input_shape (GdkWindow *window) +{ + /* CHECK: are these really supposed to be the same? */ + return _gdk_windowing_window_get_shape (window); +} + +static gboolean +_gdk_win32_window_queue_antiexpose (GdkWindow *window, + GdkRegion *area) +{ + HRGN hrgn = _gdk_win32_gdkregion_to_hrgn (area, 0, 0); + + GDK_NOTE (EVENTS, g_print ("_gdk_windowing_window_queue_antiexpose: ValidateRgn %p %s\n", + GDK_WINDOW_HWND (window), + _gdk_win32_gdkregion_to_string (area))); + + ValidateRgn (GDK_WINDOW_HWND (window), hrgn); + + DeleteObject (hrgn); + + return FALSE; +} + +/* + * queue_translation is meant to only move any outstanding invalid area + * in the given area by dx,dy. A typical example of when its needed is an + * app with two toplevels where one (A) overlaps the other (B). If the + * app first moves A so that B is invalidated and then scrolls B before + * handling the expose. The scroll operation will copy the invalid area + * to a new position, but when the invalid area is then exposed it only + * redraws the old areas not the place where the invalid data was copied + * by the scroll. + */ +static void +_gdk_win32_window_queue_translation (GdkWindow *window, + GdkGC *gc, + GdkRegion *area, + gint dx, + gint dy) +{ + HRGN hrgn = CreateRectRgn (0, 0, 0, 0); + int ret = GetUpdateRgn (GDK_WINDOW_HWND (window), hrgn, FALSE); + if (ret == ERROR) + WIN32_API_FAILED ("GetUpdateRgn"); + else if (ret != NULLREGION) + { + /* Get current updateregion, move any part of it that intersects area by dx,dy */ + HRGN update = _gdk_win32_gdkregion_to_hrgn (area, 0, 0); + ret = CombineRgn (update, hrgn, update, RGN_AND); + if (ret == ERROR) + WIN32_API_FAILED ("CombineRgn"); + else if (ret != NULLREGION) + { + OffsetRgn (update, dx, dy); + API_CALL (InvalidateRgn, (GDK_WINDOW_HWND (window), update, TRUE)); + } + DeleteObject (update); + } + DeleteObject (hrgn); +} + +static void +gdk_win32_input_shape_combine_region (GdkWindow *window, + const GdkRegion *shape_region, + gint offset_x, + gint offset_y) +{ + if (GDK_WINDOW_DESTROYED (window)) + return; + /* CHECK: are these really supposed to be the same? */ + gdk_win32_window_shape_combine_region (window, shape_region, offset_x, offset_y); +} + +void +_gdk_windowing_window_process_updates_recurse (GdkWindow *window, + GdkRegion *region) +{ + _gdk_window_process_updates_recurse (window, region); +} + +void +_gdk_windowing_before_process_all_updates (void) +{ +} + +void +_gdk_windowing_after_process_all_updates (void) +{ +} + static void gdk_window_impl_iface_init (GdkWindowImplIface *iface) { @@ -3862,22 +3645,25 @@ gdk_window_impl_iface_init (GdkWindowImplIface *iface) iface->withdraw = gdk_win32_window_withdraw; iface->set_events = gdk_win32_window_set_events; iface->get_events = gdk_win32_window_get_events; - iface->clear_area = gdk_win32_window_clear_area; iface->raise = gdk_win32_window_raise; iface->lower = gdk_win32_window_lower; + iface->restack_under = gdk_win32_window_restack_under; + iface->restack_toplevel = gdk_win32_window_restack_toplevel; iface->move_resize = gdk_win32_window_move_resize; - iface->scroll = _gdk_win32_window_scroll; - iface->move_region = _gdk_win32_window_move_region; iface->set_background = gdk_win32_window_set_background; iface->set_back_pixmap = gdk_win32_window_set_back_pixmap; iface->reparent = gdk_win32_window_reparent; iface->set_cursor = gdk_win32_window_set_cursor; iface->get_geometry = gdk_win32_window_get_geometry; - iface->get_origin = gdk_win32_window_get_origin; - iface->shape_combine_mask = gdk_win32_window_shape_combine_mask; + iface->get_pointer = gdk_window_win32_get_pointer; + iface->get_root_coords = gdk_win32_window_get_root_coords; iface->shape_combine_region = gdk_win32_window_shape_combine_region; - iface->set_child_shapes = gdk_win32_window_set_child_shapes; - iface->merge_child_shapes = gdk_win32_window_merge_child_shapes; + iface->input_shape_combine_region = gdk_win32_input_shape_combine_region; + iface->get_deskrelative_origin = gdk_win32_window_get_deskrelative_origin; iface->set_static_gravities = gdk_win32_window_set_static_gravities; - iface->get_offsets = _gdk_win32_windowing_window_get_offsets; + iface->queue_antiexpose = _gdk_win32_window_queue_antiexpose; + iface->queue_translation = _gdk_win32_window_queue_translation; + iface->destroy = _gdk_win32_window_destroy; + iface->input_window_destroy = _gdk_input_window_destroy; + iface->input_window_crossing = _gdk_input_crossing_event; } diff --git a/gdk/win32/gdkwindow-win32.h b/gdk/win32/gdkwindow-win32.h index fbc461c943..f488e59faa 100644 --- a/gdk/win32/gdkwindow-win32.h +++ b/gdk/win32/gdkwindow-win32.h @@ -33,6 +33,7 @@ G_BEGIN_DECLS typedef struct _GdkWin32PositionInfo GdkWin32PositionInfo; +#if 0 struct _GdkWin32PositionInfo { gint x; @@ -49,6 +50,7 @@ struct _GdkWin32PositionInfo */ GdkRectangle clip_rect; /* visible rectangle of window */ }; +#endif /* Window implementation for Win32 @@ -68,11 +70,6 @@ struct _GdkWindowImplWin32 { GdkDrawableImplWin32 parent_instance; - gint width; - gint height; - - GdkWin32PositionInfo position_info; - gint8 toplevel_window_type; HCURSOR hcursor; @@ -91,6 +88,8 @@ struct _GdkWindowImplWin32 GSList *transient_children; gint num_transients; gboolean changing_state; + + guint no_bg : 1; }; struct _GdkWindowImplWin32Class @@ -100,6 +99,14 @@ struct _GdkWindowImplWin32Class GType _gdk_window_impl_win32_get_type (void); +void _gdk_win32_window_tmp_unset_bg (GdkWindow *window, + gboolean recurse); +void _gdk_win32_window_tmp_reset_bg (GdkWindow *window, + gboolean recurse); + +void _gdk_win32_window_tmp_unset_parent_bg (GdkWindow *window); +void _gdk_win32_window_tmp_reset_parent_bg (GdkWindow *window); + G_END_DECLS #endif /* __GDK_WINDOW_WIN32_H__ */ diff --git a/gdk/win32/makefile.msc b/gdk/win32/makefile.msc index cb6ba5d0a5..5a4fa418f3 100644 --- a/gdk/win32/makefile.msc +++ b/gdk/win32/makefile.msc @@ -16,10 +16,13 @@ WTKIT = $(TOP)\wtkit126 GTK_VER=2.0 -CFLAGS = -FImsvc_recommended_pragmas.h \ +DEFINES = \ + -DHAVE_CONFIG_H -DINSIDE_GDK_WIN32 -DGDK_VERSION=\"$(GTK_VER)\" \ + -DGDK_COMPILATION -DG_LOG_DOMAIN=\"Gdk\" + +INCLUDES = -FImsvc_recommended_pragmas.h \ -I. -I.. -I..\.. $(GLIB_CFLAGS) $(PANGO_CFLAGS) $(CAIRO_CFLAGS) \ -I$(WTKIT)\include -I$(GLIB) \ - $(G_DEBUGGING) -DHAVE_CONFIG_H -DINSIDE_GDK_WIN32 -DGDK_VERSION=\"$(GTK_VER)\" all: \ ..\..\config.h \ @@ -68,9 +71,6 @@ gdk.res : rc\gdk.rc gdk-win32.lib : $(gdk_win32_OBJECTS) lib -out:gdk-win32.lib $(gdk_win32_OBJECTS) -.c.obj : - $(CC) $(CFLAGS) -GD -c -DGDK_COMPILATION -DG_LOG_DOMAIN=\"Gdk\" $< - clean:: del *.obj del *.lib diff --git a/gdk/x11/gdkasync.c b/gdk/x11/gdkasync.c index 3f90d59441..e412ed2f7e 100644 --- a/gdk/x11/gdkasync.c +++ b/gdk/x11/gdkasync.c @@ -57,6 +57,7 @@ typedef struct _ChildInfoState ChildInfoState; typedef struct _ListChildrenState ListChildrenState; typedef struct _SendEventState SendEventState; typedef struct _SetInputFocusState SetInputFocusState; +typedef struct _RoundtripState RoundtripState; typedef enum { CHILD_INFO_GET_PROPERTY, @@ -112,6 +113,16 @@ struct _SetInputFocusState gulong get_input_focus_req; }; +struct _RoundtripState +{ + Display *dpy; + _XAsyncHandler async; + gulong get_input_focus_req; + GdkDisplay *display; + GdkRoundTripCallback callback; + gpointer data; +}; + static gboolean callback_idle (gpointer data) { @@ -743,5 +754,92 @@ _gdk_x11_get_window_child_info (GdkDisplay *display, return !state.have_error; } +static gboolean +roundtrip_callback_idle (gpointer data) +{ + RoundtripState *state = (RoundtripState *)data; + + state->callback (state->display, state->data, state->get_input_focus_req); + + g_free (state); + + return FALSE; +} + +static Bool +roundtrip_handler (Display *dpy, + xReply *rep, + char *buf, + int len, + XPointer data) +{ + RoundtripState *state = (RoundtripState *)data; + + if (dpy->last_request_read == state->get_input_focus_req) + { + xGetInputFocusReply replbuf; + xGetInputFocusReply *repl; + + if (rep->generic.type != X_Error) + { + /* Actually does nothing, since there are no additional bytes + * to read, but maintain good form. + */ + repl = (xGetInputFocusReply *) + _XGetAsyncReply(dpy, (char *)&replbuf, rep, buf, len, + (sizeof(xGetInputFocusReply) - sizeof(xReply)) >> 2, + True); + } + + + if (state->callback) + gdk_threads_add_idle (roundtrip_callback_idle, state); + + DeqAsyncHandler(state->dpy, &state->async); + + return (rep->generic.type != X_Error); + } + + return False; +} + +void +_gdk_x11_roundtrip_async (GdkDisplay *display, + GdkRoundTripCallback callback, + gpointer data) +{ + Display *dpy; + RoundtripState *state; + + dpy = GDK_DISPLAY_XDISPLAY (display); + + state = g_new (RoundtripState, 1); + + state->display = display; + state->dpy = dpy; + state->callback = callback; + state->data = data; + + LockDisplay(dpy); + + state->async.next = dpy->async_handlers; + state->async.handler = roundtrip_handler; + state->async.data = (XPointer) state; + dpy->async_handlers = &state->async; + + /* + * XSync (dpy, 0) + */ + { + xReq *req; + + GetEmptyReq(GetInputFocus, req); + state->get_input_focus_req = dpy->request; + } + + UnlockDisplay(dpy); + SyncHandle(); +} + #define __GDK_ASYNC_C__ #include "gdkaliasdef.c" diff --git a/gdk/x11/gdkasync.h b/gdk/x11/gdkasync.h index 91897f380f..44aa18c47c 100644 --- a/gdk/x11/gdkasync.h +++ b/gdk/x11/gdkasync.h @@ -31,6 +31,9 @@ typedef struct _GdkChildInfoX11 GdkChildInfoX11; typedef void (*GdkSendXEventCallback) (Window window, gboolean success, gpointer data); +typedef void (*GdkRoundTripCallback) (GdkDisplay *display, + gpointer data, + gulong serial); struct _GdkChildInfoX11 { @@ -63,6 +66,10 @@ gboolean _gdk_x11_get_window_child_info (GdkDisplay *display, GdkChildInfoX11 **children, guint *nchildren); +void _gdk_x11_roundtrip_async (GdkDisplay *display, + GdkRoundTripCallback callback, + gpointer data); + G_END_DECLS #endif /* __GDK_ASYNC_H__ */ diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c index 735ac5734d..2b10a93618 100644 --- a/gdk/x11/gdkdisplay-x11.c +++ b/gdk/x11/gdkdisplay-x11.c @@ -31,6 +31,7 @@ #include #include "gdkx.h" +#include "gdkasync.h" #include "gdkdisplay.h" #include "gdkdisplay-x11.h" #include "gdkscreen.h" @@ -401,8 +402,7 @@ gdk_display_open (const gchar *display_name) _gdk_dnd_init (display); for (i = 0; i < ScreenCount (display_x11->xdisplay); i++) - gdk_display_request_selection_notification (display, - GDK_SCREEN_X11 (display_x11->screens[i])->cm_selection_atom); + _gdk_x11_screen_setup (display_x11->screens[i]); g_signal_emit_by_name (gdk_display_manager_get(), "display_opened", display); @@ -439,6 +439,13 @@ process_internal_connection (GIOChannel *gioc, return TRUE; } +gulong +_gdk_windowing_window_get_next_serial (GdkDisplay *display) +{ + return NextRequest (GDK_DISPLAY_XDISPLAY (display)); +} + + static GdkInternalConnection * gdk_add_connection_handler (Display *display, guint fd) @@ -579,6 +586,20 @@ _gdk_x11_display_is_root_window (GdkDisplay *display, return FALSE; } +struct XPointerUngrabInfo { + GdkDisplay *display; + guint32 time; +}; + +static void +pointer_ungrab_callback (GdkDisplay *display, + gpointer data, + gulong serial) +{ + _gdk_display_pointer_grab_update (display, serial); +} + + #define XSERVER_TIME_IS_LATER(time1, time2) \ ( (( time1 > time2 ) && ( time1 - time2 < ((guint32)-1)/2 )) || \ (( time1 < time2 ) && ( time2 - time1 > ((guint32)-1)/2 )) \ @@ -595,43 +616,35 @@ _gdk_x11_display_is_root_window (GdkDisplay *display, */ void gdk_display_pointer_ungrab (GdkDisplay *display, - guint32 time) + guint32 time_) { Display *xdisplay; GdkDisplayX11 *display_x11; + GdkPointerGrabInfo *grab; + unsigned long serial; g_return_if_fail (GDK_IS_DISPLAY (display)); display_x11 = GDK_DISPLAY_X11 (display); xdisplay = GDK_DISPLAY_XDISPLAY (display); + + serial = NextRequest (xdisplay); - _gdk_input_ungrab_pointer (display, time); - XUngrabPointer (xdisplay, time); + _gdk_input_ungrab_pointer (display, time_); + XUngrabPointer (xdisplay, time_); XFlush (xdisplay); - if (time == GDK_CURRENT_TIME || - display_x11->pointer_xgrab_time == GDK_CURRENT_TIME || - !XSERVER_TIME_IS_LATER (display_x11->pointer_xgrab_time, time)) - display_x11->pointer_xgrab_window = NULL; -} - -/** - * gdk_display_pointer_is_grabbed: - * @display: a #GdkDisplay - * - * Test if the pointer is grabbed. - * - * Returns: %TRUE if an active X pointer grab is in effect - * - * Since: 2.2 - */ -gboolean -gdk_display_pointer_is_grabbed (GdkDisplay *display) -{ - g_return_val_if_fail (GDK_IS_DISPLAY (display), TRUE); - - return (GDK_DISPLAY_X11 (display)->pointer_xgrab_window != NULL && - !GDK_DISPLAY_X11 (display)->pointer_xgrab_implicit); + grab = _gdk_display_get_last_pointer_grab (display); + if (grab && + (time_ == GDK_CURRENT_TIME || + grab->time == GDK_CURRENT_TIME || + !XSERVER_TIME_IS_LATER (grab->time, time_))) + { + grab->serial_end = serial; + _gdk_x11_roundtrip_async (display, + pointer_ungrab_callback, + NULL); + } } /** @@ -659,9 +672,9 @@ gdk_display_keyboard_ungrab (GdkDisplay *display, XFlush (xdisplay); if (time == GDK_CURRENT_TIME || - display_x11->keyboard_xgrab_time == GDK_CURRENT_TIME || - !XSERVER_TIME_IS_LATER (display_x11->keyboard_xgrab_time, time)) - display_x11->keyboard_xgrab_window = NULL; + display->keyboard_grab.time == GDK_CURRENT_TIME || + !XSERVER_TIME_IS_LATER (display->keyboard_grab.time, time)) + _gdk_display_unset_has_keyboard_grab (display, FALSE); } /** @@ -676,8 +689,8 @@ void gdk_display_beep (GdkDisplay *display) { g_return_if_fail (GDK_IS_DISPLAY (display)); - - XBell (GDK_DISPLAY_XDISPLAY (display), 0); + + XkbBell (GDK_DISPLAY_XDISPLAY (display), None, 0, None); } /** @@ -1330,7 +1343,9 @@ gdk_display_store_clipboard (GdkDisplay *display, { GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display); Atom clipboard_manager, save_targets; - + + g_return_if_fail (GDK_WINDOW_IS_X11 (clipboard_window)); + clipboard_manager = gdk_x11_get_xatom_by_name_for_display (display, "CLIPBOARD_MANAGER"); save_targets = gdk_x11_get_xatom_by_name_for_display (display, "SAVE_TARGETS"); diff --git a/gdk/x11/gdkdisplay-x11.h b/gdk/x11/gdkdisplay-x11.h index 0ade8f0835..2873c2d674 100644 --- a/gdk/x11/gdkdisplay-x11.h +++ b/gdk/x11/gdkdisplay-x11.h @@ -30,6 +30,7 @@ #include #include #include +#include #include /* For gdk_get_program_class() */ G_BEGIN_DECLS @@ -93,21 +94,6 @@ struct _GdkDisplayX11 * (grabs, properties etc.) Otherwise always TRUE. */ gboolean trusted_client; - /* Information about current pointer and keyboard grabs held by this - * client. If gdk_pointer_xgrab_window or gdk_keyboard_xgrab_window - * window is NULL, then the other associated fields are ignored - */ - GdkWindowObject *pointer_xgrab_window; - gulong pointer_xgrab_serial; - gboolean pointer_xgrab_owner_events; - gboolean pointer_xgrab_implicit; - guint32 pointer_xgrab_time; - - GdkWindowObject *keyboard_xgrab_window; - gulong keyboard_xgrab_serial; - gboolean keyboard_xgrab_owner_events; - guint32 keyboard_xgrab_time; - /* drag and drop information */ GdkDragContext *current_dest_drag; @@ -147,11 +133,6 @@ struct _GdkDisplayX11 /* input GdkWindow list */ GList *input_windows; - gint input_ignore_core; - /* information about network port and host for gxid daemon */ - gchar *input_gxid_host; - gint input_gxid_port; - /* Startup notification */ gchar *startup_notification_id; @@ -169,6 +150,9 @@ struct _GdkDisplayX11 /* Alpha mask picture format */ XRenderPictFormat *mask_format; + + /* The offscreen window that has the pointer in it (if any) */ + GdkWindow *active_offscreen_window; }; struct _GdkDisplayX11Class diff --git a/gdk/x11/gdkdnd-x11.c b/gdk/x11/gdkdnd-x11.c index 82ef442265..118d793c79 100644 --- a/gdk/x11/gdkdnd-x11.c +++ b/gdk/x11/gdkdnd-x11.c @@ -2992,6 +2992,7 @@ gdk_drag_begin (GdkWindow *window, GdkDragContext *new_context; g_return_val_if_fail (window != NULL, NULL); + g_return_val_if_fail (GDK_WINDOW_IS_X11 (window), NULL); new_context = gdk_drag_context_new (); new_context->is_source = TRUE; @@ -3197,7 +3198,7 @@ gdk_drag_find_window_for_screen (GdkDragContext *context, window_cache = drag_context_find_window_cache (context, screen); dest = get_client_window_at_coords (window_cache, - drag_window ? + drag_window && GDK_WINDOW_IS_X11 (drag_window) ? GDK_DRAWABLE_XID (drag_window) : None, x_root, y_root); @@ -3267,6 +3268,7 @@ gdk_drag_motion (GdkDragContext *context, GdkDragContextPrivateX11 *private = PRIVATE_DATA (context); g_return_val_if_fail (context != NULL, FALSE); + g_return_val_if_fail (dest_window == NULL || GDK_WINDOW_IS_X11 (dest_window), FALSE); private->old_actions = context->actions; context->actions = possible_actions; diff --git a/gdk/x11/gdkdrawable-x11.c b/gdk/x11/gdkdrawable-x11.c index a19c7a2e2c..ab98b7fcd2 100644 --- a/gdk/x11/gdkdrawable-x11.c +++ b/gdk/x11/gdkdrawable-x11.c @@ -93,7 +93,8 @@ static void gdk_x11_draw_drawable (GdkDrawable *drawable, gint xdest, gint ydest, gint width, - gint height); + gint height, + GdkDrawable *original_src); static void gdk_x11_draw_points (GdkDrawable *drawable, GdkGC *gc, GdkPoint *points, @@ -159,7 +160,7 @@ _gdk_drawable_impl_x11_class_init (GdkDrawableImplX11Class *klass) drawable_class->draw_polygon = gdk_x11_draw_polygon; drawable_class->draw_text = gdk_x11_draw_text; drawable_class->draw_text_wc = gdk_x11_draw_text_wc; - drawable_class->draw_drawable = gdk_x11_draw_drawable; + drawable_class->draw_drawable_with_src = gdk_x11_draw_drawable; drawable_class->draw_points = gdk_x11_draw_points; drawable_class->draw_segments = gdk_x11_draw_segments; drawable_class->draw_lines = gdk_x11_draw_lines; @@ -387,9 +388,22 @@ gdk_x11_drawable_update_picture_clip (GdkDrawable *drawable, else { XRenderPictureAttributes pa; - pa.clip_mask = None; + GdkBitmap *mask; + gulong pa_mask; + + pa_mask = CPClipMask; + if (gc && (mask = _gdk_gc_get_clip_mask (gc))) + { + pa.clip_mask = GDK_PIXMAP_XID (mask); + pa.clip_x_origin = gc->clip_x_origin; + pa.clip_y_origin = gc->clip_y_origin; + pa_mask |= CPClipXOrigin | CPClipYOrigin; + } + else + pa.clip_mask = None; + XRenderChangePicture (xdisplay, picture, - CPClipMask, &pa); + pa_mask, &pa); } } @@ -623,7 +637,8 @@ gdk_x11_draw_drawable (GdkDrawable *drawable, gint xdest, gint ydest, gint width, - gint height) + gint height, + GdkDrawable *original_src) { int src_depth = gdk_drawable_get_depth (src); int dest_depth = gdk_drawable_get_depth (drawable); @@ -634,13 +649,50 @@ gdk_x11_draw_drawable (GdkDrawable *drawable, if (GDK_IS_DRAWABLE_IMPL_X11 (src)) src_impl = GDK_DRAWABLE_IMPL_X11 (src); + else if (GDK_IS_WINDOW (src)) + src_impl = GDK_DRAWABLE_IMPL_X11(((GdkWindowObject *)src)->impl); else - src_impl = NULL; + src_impl = GDK_DRAWABLE_IMPL_X11(((GdkPixmapObject *)src)->impl); + + if (GDK_IS_WINDOW_IMPL_X11 (impl) && + GDK_IS_PIXMAP_IMPL_X11 (src_impl)) + { + GdkPixmapImplX11 *src_pixmap = GDK_PIXMAP_IMPL_X11 (src_impl); + /* Work around an Xserver bug where non-visible areas from + * a pixmap to a window will clear the window background + * in destination areas that are supposed to be clipped out. + * This is a problem with client side windows as this means + * things may draw outside the virtual windows. This could + * also happen for window to window copies, but I don't + * think we generate any calls like that. + * + * See: + * http://lists.freedesktop.org/archives/xorg/2009-February/043318.html + */ + if (xsrc < 0) + { + width += xsrc; + xdest -= xsrc; + xsrc = 0; + } + + if (ysrc < 0) + { + height += ysrc; + ydest -= ysrc; + ysrc = 0; + } + + if (xsrc + width > src_pixmap->width) + width = src_pixmap->width - xsrc; + if (ysrc + height > src_pixmap->height) + height = src_pixmap->height - ysrc; + } if (src_depth == 1) { XCopyArea (GDK_SCREEN_XDISPLAY (impl->screen), - src_impl ? src_impl->xid : GDK_DRAWABLE_XID (src), + src_impl->xid, impl->xid, GDK_GC_GET_XGC (gc), xsrc, ysrc, @@ -650,7 +702,7 @@ gdk_x11_draw_drawable (GdkDrawable *drawable, else if (dest_depth != 0 && src_depth == dest_depth) { XCopyArea (GDK_SCREEN_XDISPLAY (impl->screen), - src_impl ? src_impl->xid : GDK_DRAWABLE_XID (src), + src_impl->xid, impl->xid, GDK_GC_GET_XGC (gc), xsrc, ysrc, @@ -870,7 +922,29 @@ gdk_x11_drawable_get_xid (GdkDrawable *drawable) GdkDrawable *impl; if (GDK_IS_WINDOW (drawable)) - impl = ((GdkPixmapObject *)drawable)->impl; + { + GdkWindow *window = (GdkWindow *)drawable; + + /* Try to ensure the window has a native window */ + if (!_gdk_window_has_impl (window)) + { + gdk_window_ensure_native (window); + + /* We sync here to ensure the window is created in the Xserver when + * this function returns. This is required because the returned XID + * for this window must be valid immediately, even with another + * connection to the Xserver */ + gdk_display_sync (gdk_drawable_get_display (window)); + } + + if (!GDK_WINDOW_IS_X11 (window)) + { + g_warning (G_STRLOC " drawable is not a native X11 window"); + return None; + } + + impl = ((GdkWindowObject *)drawable)->impl; + } else if (GDK_IS_PIXMAP (drawable)) impl = ((GdkPixmapObject *)drawable)->impl; else @@ -882,6 +956,17 @@ gdk_x11_drawable_get_xid (GdkDrawable *drawable) return ((GdkDrawableImplX11 *)impl)->xid; } +GdkDrawable * +gdk_x11_window_get_drawable_impl (GdkWindow *window) +{ + return ((GdkWindowObject *)window)->impl; +} +GdkDrawable * +gdk_x11_pixmap_get_drawable_impl (GdkPixmap *pixmap) +{ + return ((GdkPixmapObject *)pixmap)->impl; +} + /* Code for accelerated alpha compositing using the RENDER extension. * It's a bit long because there are lots of possibilities for * what's the fastest depending on the available picture formats, @@ -1447,6 +1532,45 @@ gdk_x11_cairo_surface_destroy (void *data) impl->cairo_surface = NULL; } +void +_gdk_windowing_set_cairo_surface_size (cairo_surface_t *surface, + int width, + int height) +{ + cairo_xlib_surface_set_size (surface, width, height); +} + +cairo_surface_t * +_gdk_windowing_create_cairo_surface (GdkDrawable *drawable, + int width, + int height) +{ + GdkDrawableImplX11 *impl = GDK_DRAWABLE_IMPL_X11 (drawable); + GdkVisual *visual; + + visual = gdk_drawable_get_visual (drawable); + if (visual) + return cairo_xlib_surface_create (GDK_SCREEN_XDISPLAY (impl->screen), + impl->xid, + GDK_VISUAL_XVISUAL (visual), + width, height); + else if (gdk_drawable_get_depth (drawable) == 1) + return cairo_xlib_surface_create_for_bitmap (GDK_SCREEN_XDISPLAY (impl->screen), + impl->xid, + GDK_SCREEN_XSCREEN (impl->screen), + width, height); + else + { + g_warning ("Using Cairo rendering requires the drawable argument to\n" + "have a specified colormap. All windows have a colormap,\n" + "however, pixmaps only have colormap by default if they\n" + "were created with a non-NULL window argument. Otherwise\n" + "a colormap must be set on them with gdk_drawable_set_colormap"); + return NULL; + } + +} + static cairo_surface_t * gdk_x11_ref_cairo_surface (GdkDrawable *drawable) { @@ -1458,35 +1582,15 @@ gdk_x11_ref_cairo_surface (GdkDrawable *drawable) if (!impl->cairo_surface) { - GdkVisual *visual = NULL; int width, height; - visual = gdk_drawable_get_visual (drawable); - gdk_drawable_get_size (drawable, &width, &height); - if (visual) - impl->cairo_surface = cairo_xlib_surface_create (GDK_SCREEN_XDISPLAY (impl->screen), - impl->xid, - GDK_VISUAL_XVISUAL (visual), - width, height); - else if (gdk_drawable_get_depth (drawable) == 1) - impl->cairo_surface = cairo_xlib_surface_create_for_bitmap (GDK_SCREEN_XDISPLAY (impl->screen), - impl->xid, - GDK_SCREEN_XSCREEN (impl->screen), - width, height); - else - { - g_warning ("Using Cairo rendering requires the drawable argument to\n" - "have a specified colormap. All windows have a colormap,\n" - "however, pixmaps only have colormap by default if they\n" - "were created with a non-NULL window argument. Otherwise\n" - "a colormap must be set on them with gdk_drawable_set_colormap"); - return NULL; - } - - cairo_surface_set_user_data (impl->cairo_surface, &gdk_x11_cairo_key, - drawable, gdk_x11_cairo_surface_destroy); + impl->cairo_surface = _gdk_windowing_create_cairo_surface (drawable, width, height); + + if (impl->cairo_surface) + cairo_surface_set_user_data (impl->cairo_surface, &gdk_x11_cairo_key, + drawable, gdk_x11_cairo_surface_destroy); } else cairo_surface_reference (impl->cairo_surface); diff --git a/gdk/x11/gdkdrawable-x11.h b/gdk/x11/gdkdrawable-x11.h index 7ff60085a1..2b885366f0 100644 --- a/gdk/x11/gdkdrawable-x11.h +++ b/gdk/x11/gdkdrawable-x11.h @@ -92,6 +92,8 @@ void _gdk_x11_convert_to_format (guchar *src_buf, /* Note that the following take GdkDrawableImplX11, not the wrapper drawable */ void _gdk_x11_drawable_finish (GdkDrawable *drawable); void _gdk_x11_drawable_update_size (GdkDrawable *drawable); +GdkDrawable *gdk_x11_window_get_drawable_impl (GdkWindow *window); +GdkDrawable *gdk_x11_pixmap_get_drawable_impl (GdkPixmap *pixmap); G_END_DECLS diff --git a/gdk/x11/gdkevents-x11.c b/gdk/x11/gdkevents-x11.c index 359471de9e..e2cae06410 100644 --- a/gdk/x11/gdkevents-x11.c +++ b/gdk/x11/gdkevents-x11.c @@ -305,6 +305,8 @@ graphics_expose_predicate (Display *display, * * Return value: a #GdkEventExpose if a GraphicsExpose was received, or %NULL if a * NoExpose event was received. + * + * Deprecated:2.18 **/ GdkEvent* gdk_event_get_graphics_expose (GdkWindow *window) @@ -313,7 +315,7 @@ gdk_event_get_graphics_expose (GdkWindow *window) GdkEvent *event; g_return_val_if_fail (window != NULL, NULL); - + XIfEvent (GDK_WINDOW_XDISPLAY (window), &xevent, graphics_expose_predicate, (XPointer) window); @@ -867,6 +869,24 @@ set_user_time (GdkWindow *window, gdk_event_get_time (event)); } +static gboolean +is_parent_of (GdkWindow *parent, + GdkWindow *child) +{ + GdkWindow *w; + + w = child; + while (w != NULL) + { + if (w == parent) + return TRUE; + + w = gdk_window_get_parent (w); + } + + return FALSE; +} + static gboolean gdk_event_translate (GdkDisplay *display, GdkEvent *event, @@ -879,7 +899,6 @@ gdk_event_translate (GdkDisplay *display, GdkWindow *filter_window; GdkWindowImplX11 *window_impl = NULL; gboolean return_val; - gint xoffset, yoffset; GdkScreen *screen = NULL; GdkScreenX11 *screen_x11 = NULL; GdkToplevelX11 *toplevel = NULL; @@ -942,6 +961,24 @@ gdk_event_translate (GdkDisplay *display, if (window != NULL) { + /* Apply keyboard grabs to non-native windows */ + if (/* Is key event */ + (xevent->type == KeyPress || xevent->type == KeyRelease) && + /* And we have a grab */ + display->keyboard_grab.window != NULL && + ( + /* The window is not a descendant of the grabbed window */ + !is_parent_of ((GdkWindow *)display->keyboard_grab.window, window) || + /* Or owner event is false */ + !display->keyboard_grab.owner_events + ) + ) + { + /* Report key event against grab window */ + window = display->keyboard_grab.window;; + window_private = (GdkWindowObject *) window; + } + window_impl = GDK_WINDOW_IMPL_X11 (window_private->impl); /* Move key events on focus window to the real toplevel, and @@ -997,28 +1034,31 @@ gdk_event_translate (GdkDisplay *display, } } } - - if (screen_x11 && screen_x11->wmspec_check_window != None && - xwindow == screen_x11->wmspec_check_window) - { - if (xevent->type == DestroyNotify) - { - screen_x11->wmspec_check_window = None; - g_free (screen_x11->window_manager_name); - screen_x11->window_manager_name = g_strdup ("unknown"); - /* careful, reentrancy */ - _gdk_x11_screen_window_manager_changed (GDK_SCREEN (screen_x11)); + if (xevent->type == DestroyNotify) + { + int i, n; + + n = gdk_display_get_n_screens (display); + for (i = 0; i < n; i++) + { + screen = gdk_display_get_screen (display, i); + screen_x11 = GDK_SCREEN_X11 (screen); + + if (screen_x11->wmspec_check_window == xwindow) + { + screen_x11->wmspec_check_window = None; + screen_x11->last_wmspec_check_time = 0; + g_free (screen_x11->window_manager_name); + screen_x11->window_manager_name = g_strdup ("unknown"); + + /* careful, reentrancy */ + _gdk_x11_screen_window_manager_changed (screen); + + return_val = FALSE; + goto done; + } } - - /* Eat events on this window unless someone had wrapped - * it as a foreign window - */ - if (window == NULL) - { - return_val = FALSE; - goto done; - } } if (window && @@ -1041,16 +1081,6 @@ gdk_event_translate (GdkDisplay *display, return_val = TRUE; - if (window) - { - _gdk_x11_window_get_offsets (window, &xoffset, &yoffset); - } - else - { - xoffset = 0; - yoffset = 0; - } - switch (xevent->type) { case KeyPress: @@ -1100,9 +1130,7 @@ gdk_event_translate (GdkDisplay *display, xevent->xbutton.x, xevent->xbutton.y, xevent->xbutton.button)); - if (window_private == NULL || - ((window_private->extension_events != 0) && - display_x11->input_ignore_core)) + if (window_private == NULL) { return_val = FALSE; break; @@ -1129,8 +1157,8 @@ gdk_event_translate (GdkDisplay *display, event->scroll.window = window; event->scroll.time = xevent->xbutton.time; - event->scroll.x = xevent->xbutton.x + xoffset; - event->scroll.y = xevent->xbutton.y + yoffset; + event->scroll.x = xevent->xbutton.x; + event->scroll.y = xevent->xbutton.y; event->scroll.x_root = (gfloat)xevent->xbutton.x_root; event->scroll.y_root = (gfloat)xevent->xbutton.y_root; event->scroll.state = (GdkModifierType) xevent->xbutton.state; @@ -1148,8 +1176,8 @@ gdk_event_translate (GdkDisplay *display, event->button.type = GDK_BUTTON_PRESS; event->button.window = window; event->button.time = xevent->xbutton.time; - event->button.x = xevent->xbutton.x + xoffset; - event->button.y = xevent->xbutton.y + yoffset; + event->button.x = xevent->xbutton.x; + event->button.y = xevent->xbutton.y; event->button.x_root = (gfloat)xevent->xbutton.x_root; event->button.y_root = (gfloat)xevent->xbutton.y_root; event->button.axes = NULL; @@ -1162,14 +1190,11 @@ gdk_event_translate (GdkDisplay *display, return_val = FALSE; break; } - - _gdk_event_button_generate (display, event); break; } set_user_time (window, event); - _gdk_xgrab_check_button_event (window, xevent); break; case ButtonRelease: @@ -1179,9 +1204,7 @@ gdk_event_translate (GdkDisplay *display, xevent->xbutton.x, xevent->xbutton.y, xevent->xbutton.button)); - if (window_private == NULL || - ((window_private->extension_events != 0) && - display_x11->input_ignore_core)) + if (window_private == NULL) { return_val = FALSE; break; @@ -1198,8 +1221,8 @@ gdk_event_translate (GdkDisplay *display, event->button.type = GDK_BUTTON_RELEASE; event->button.window = window; event->button.time = xevent->xbutton.time; - event->button.x = xevent->xbutton.x + xoffset; - event->button.y = xevent->xbutton.y + yoffset; + event->button.x = xevent->xbutton.x; + event->button.y = xevent->xbutton.y; event->button.x_root = (gfloat)xevent->xbutton.x_root; event->button.y_root = (gfloat)xevent->xbutton.y_root; event->button.axes = NULL; @@ -1208,12 +1231,8 @@ gdk_event_translate (GdkDisplay *display, event->button.device = display->core_pointer; if (!set_screen_from_root (display, event, xevent->xbutton.root)) - { - return_val = FALSE; - break; - } - - _gdk_xgrab_check_button_event (window, xevent); + return_val = FALSE; + break; case MotionNotify: @@ -1223,9 +1242,7 @@ gdk_event_translate (GdkDisplay *display, xevent->xmotion.x, xevent->xmotion.y, (xevent->xmotion.is_hint) ? "true" : "false")); - if (window_private == NULL || - ((window_private->extension_events != 0) && - display_x11->input_ignore_core)) + if (window_private == NULL) { return_val = FALSE; break; @@ -1234,8 +1251,8 @@ gdk_event_translate (GdkDisplay *display, event->motion.type = GDK_MOTION_NOTIFY; event->motion.window = window; event->motion.time = xevent->xmotion.time; - event->motion.x = xevent->xmotion.x + xoffset; - event->motion.y = xevent->xmotion.y + yoffset; + event->motion.x = xevent->xmotion.x; + event->motion.y = xevent->xmotion.y; event->motion.x_root = (gfloat)xevent->xmotion.x_root; event->motion.y_root = (gfloat)xevent->xmotion.y_root; event->motion.axes = NULL; @@ -1253,11 +1270,12 @@ gdk_event_translate (GdkDisplay *display, case EnterNotify: GDK_NOTE (EVENTS, - g_message ("enter notify:\t\twindow: %ld detail: %d subwin: %ld", - xevent->xcrossing.window, - xevent->xcrossing.detail, - xevent->xcrossing.subwindow)); - + g_message ("enter notify:\t\twindow: %ld detail: %d subwin: %ld mode: %d", + xevent->xcrossing.window, + xevent->xcrossing.detail, + xevent->xcrossing.subwindow, + xevent->xcrossing.mode)); + if (window_private == NULL) { return_val = FALSE; @@ -1286,12 +1304,6 @@ gdk_event_translate (GdkDisplay *display, } } - /* Tell XInput stuff about it if appropriate */ - if (window_private && - !GDK_WINDOW_DESTROYED (window) && - window_private->extension_events != 0) - _gdk_input_enter_event (&xevent->xcrossing, window); - event->crossing.type = GDK_ENTER_NOTIFY; event->crossing.window = window; @@ -1304,8 +1316,8 @@ gdk_event_translate (GdkDisplay *display, event->crossing.subwindow = NULL; event->crossing.time = xevent->xcrossing.time; - event->crossing.x = xevent->xcrossing.x + xoffset; - event->crossing.y = xevent->xcrossing.y + yoffset; + event->crossing.x = xevent->xcrossing.x; + event->crossing.y = xevent->xcrossing.y; event->crossing.x_root = xevent->xcrossing.x_root; event->crossing.y_root = xevent->xcrossing.y_root; @@ -1355,9 +1367,11 @@ gdk_event_translate (GdkDisplay *display, case LeaveNotify: GDK_NOTE (EVENTS, - g_message ("leave notify:\t\twindow: %ld detail: %d subwin: %ld", - xevent->xcrossing.window, - xevent->xcrossing.detail, xevent->xcrossing.subwindow)); + g_message ("leave notify:\t\twindow: %ld detail: %d subwin: %ld mode: %d", + xevent->xcrossing.window, + xevent->xcrossing.detail, + xevent->xcrossing.subwindow, + xevent->xcrossing.mode)); if (window_private == NULL) { @@ -1399,8 +1413,8 @@ gdk_event_translate (GdkDisplay *display, event->crossing.subwindow = NULL; event->crossing.time = xevent->xcrossing.time; - event->crossing.x = xevent->xcrossing.x + xoffset; - event->crossing.y = xevent->xcrossing.y + yoffset; + event->crossing.x = xevent->xcrossing.x; + event->crossing.y = xevent->xcrossing.y; event->crossing.x_root = xevent->xcrossing.x_root; event->crossing.y_root = xevent->xcrossing.y_root; @@ -1586,40 +1600,25 @@ gdk_event_translate (GdkDisplay *display, xevent->xexpose.x, xevent->xexpose.y, xevent->xexpose.width, xevent->xexpose.height, event->any.send_event ? " (send)" : "")); - + if (window_private == NULL) { return_val = FALSE; break; } - + { GdkRectangle expose_rect; - expose_rect.x = xevent->xexpose.x + xoffset; - expose_rect.y = xevent->xexpose.y + yoffset; + expose_rect.x = xevent->xexpose.x; + expose_rect.y = xevent->xexpose.y; expose_rect.width = xevent->xexpose.width; expose_rect.height = xevent->xexpose.height; - if (return_exposes) - { - event->expose.type = GDK_EXPOSE; - event->expose.area = expose_rect; - event->expose.region = gdk_region_rectangle (&expose_rect); - event->expose.window = window; - event->expose.count = xevent->xexpose.count; - - return_val = TRUE; - } - else - { - _gdk_window_process_expose (window, xevent->xexpose.serial, &expose_rect); - return_val = FALSE; - } - - return_val = FALSE; + _gdk_window_process_expose (window, xevent->xexpose.serial, &expose_rect); + return_val = FALSE; } - + break; case GraphicsExpose: @@ -1636,8 +1635,8 @@ gdk_event_translate (GdkDisplay *display, break; } - expose_rect.x = xevent->xgraphicsexpose.x + xoffset; - expose_rect.y = xevent->xgraphicsexpose.y + yoffset; + expose_rect.x = xevent->xgraphicsexpose.x; + expose_rect.y = xevent->xgraphicsexpose.y; expose_rect.width = xevent->xgraphicsexpose.width; expose_rect.height = xevent->xgraphicsexpose.height; @@ -1826,9 +1825,10 @@ gdk_event_translate (GdkDisplay *display, : "")); if (window && GDK_WINDOW_TYPE (window) == GDK_WINDOW_ROOT) { - window_impl->width = xevent->xconfigure.width; - window_impl->height = xevent->xconfigure.height; - + window_private->width = xevent->xconfigure.width; + window_private->height = xevent->xconfigure.height; + + _gdk_window_update_size (window); _gdk_x11_drawable_update_size (window_private->impl); _gdk_x11_screen_size_changed (screen, xevent); } @@ -1836,7 +1836,7 @@ gdk_event_translate (GdkDisplay *display, if (window && xevent->xconfigure.event == xevent->xconfigure.window && !GDK_WINDOW_DESTROYED (window) && - (window_private->extension_events != 0)) + window_private->input_window != NULL) _gdk_input_configure_event (&xevent->xconfigure, window); #ifdef HAVE_XSYNC @@ -1847,7 +1847,7 @@ gdk_event_translate (GdkDisplay *display, } #endif - if (!window || + if (!window || xevent->xconfigure.event != xevent->xconfigure.window || GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD || GDK_WINDOW_TYPE (window) == GDK_WINDOW_ROOT) @@ -1887,9 +1887,10 @@ gdk_event_translate (GdkDisplay *display, } window_private->x = event->configure.x; window_private->y = event->configure.y; - window_impl->width = xevent->xconfigure.width; - window_impl->height = xevent->xconfigure.height; + window_private->width = xevent->xconfigure.width; + window_private->height = xevent->xconfigure.height; + _gdk_window_update_size (window); _gdk_x11_drawable_update_size (window_private->impl); if (window_private->resize_count >= 1) @@ -2152,8 +2153,8 @@ gdk_event_translate (GdkDisplay *display, if (window_private && !GDK_WINDOW_DESTROYED (window_private) && - (window_private->extension_events != 0)) - return_val = _gdk_input_other_event(event, xevent, window); + window_private->input_window) + return_val = _gdk_input_other_event (event, xevent, window); else return_val = FALSE; @@ -2180,7 +2181,7 @@ gdk_event_translate (GdkDisplay *display, if (window) g_object_unref (window); - + return return_val; } @@ -2301,6 +2302,7 @@ _gdk_events_queue (GdkDisplay *display) if (gdk_event_translate (display, event, &xevent, FALSE)) { ((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING; + _gdk_windowing_got_event (display, node, event, xevent.xany.serial); } else { @@ -2617,23 +2619,24 @@ fetch_net_wm_check_window (GdkScreen *screen) guchar *data; Window *xwindow; GTimeVal tv; - + gint error; + screen_x11 = GDK_SCREEN_X11 (screen); display = screen_x11->display; g_return_if_fail (GDK_DISPLAY_X11 (display)->trusted_client); g_get_current_time (&tv); - + if (ABS (tv.tv_sec - screen_x11->last_wmspec_check_time) < 15) return; /* we've checked recently */ screen_x11->last_wmspec_check_time = tv.tv_sec; data = NULL; - XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), screen_x11->xroot_window, + XGetWindowProperty (screen_x11->xdisplay, screen_x11->xroot_window, gdk_x11_get_xatom_by_name_for_display (display, "_NET_SUPPORTING_WM_CHECK"), - 0, G_MAXLONG, False, XA_WINDOW, &type, &format, + 0, G_MAXLONG, False, XA_WINDOW, &type, &format, &n_items, &bytes_after, &data); if (type != XA_WINDOW) @@ -2652,22 +2655,28 @@ fetch_net_wm_check_window (GdkScreen *screen) } gdk_error_trap_push (); - + /* Find out if this WM goes away, so we can reset everything. */ XSelectInput (screen_x11->xdisplay, *xwindow, StructureNotifyMask); gdk_display_sync (display); - if (gdk_error_trap_pop () == Success) + error = gdk_error_trap_pop (); + if (!error) { screen_x11->wmspec_check_window = *xwindow; screen_x11->need_refetch_net_supported = TRUE; screen_x11->need_refetch_wm_name = TRUE; - + /* Careful, reentrancy */ _gdk_x11_screen_window_manager_changed (GDK_SCREEN (screen_x11)); } + else if (error == BadWindow) + { + /* Leftover property, try again immediately, new wm may be starting up */ + screen_x11->last_wmspec_check_time = 0; + } - XFree (xwindow); + XFree (xwindow); } /** diff --git a/gdk/x11/gdkgc-x11.c b/gdk/x11/gdkgc-x11.c index 8c3e340719..0a6869a215 100644 --- a/gdk/x11/gdkgc-x11.c +++ b/gdk/x11/gdkgc-x11.c @@ -608,7 +608,8 @@ gdk_x11_gc_values_to_xvalues (GdkGCValues *values, void _gdk_windowing_gc_set_clip_region (GdkGC *gc, - const GdkRegion *region) + const GdkRegion *region, + gboolean reset_origin) { GdkGCX11 *x11_gc = GDK_GC_X11 (gc); @@ -623,8 +624,11 @@ _gdk_windowing_gc_set_clip_region (GdkGC *gc, x11_gc->have_clip_region = region != NULL; - gc->clip_x_origin = 0; - gc->clip_y_origin = 0; + if (reset_origin) + { + gc->clip_x_origin = 0; + gc->clip_y_origin = 0; + } x11_gc->dirty_mask |= GDK_GC_DIRTY_CLIP; } diff --git a/gdk/x11/gdkgeometry-x11.c b/gdk/x11/gdkgeometry-x11.c index 9271f090d5..7917031526 100644 --- a/gdk/x11/gdkgeometry-x11.c +++ b/gdk/x11/gdkgeometry-x11.c @@ -17,118 +17,6 @@ * Boston, MA 02111-1307, USA. */ -/* gdkgeometry-x11.c: emulation of 32 bit coordinates within the - * limits of X. - * - * By Owen Taylor - * Copyright Red Hat, Inc. 2000 - * - * The algorithms implemented in this file are an extension of the - * idea of guffaw scrolling, a technique (and name) taken from the classic - * Netscape source code. The basic idea of guffaw scrolling is a trick - * to get around a limitation of X: there is no way of scrolling the - * contents of a window. Guffaw scrolling exploits the X concepts of - * window gravity and bit gravity: - * - * window gravity: the window gravity of a window affects what happens - * to a windows position when _its parent_ is resized, or - * moved and resized simultaneously. - * - * bit gravity: the bit gravity of a window affects what happens to - * the pixels of a window when _it_ is is resized, or moved and - * resized simultaneously. - * - * These were basically intended to do things like have right - * justified widgets in a window automatically stay right justified - * when the window was resized, but there is also the special - * "StaticGravity" which means "do nothing." We can exploit - * StaticGravity to scroll a window: - * - * | VISIBLE | - * - * |abcdefghijk| - * |abcdefghijk | (1) Resize bigger - * | efghijk | (2) Move - * |efghijk | (3) Move-resize back to the original size - * - * Or, going the other way: - - * |abcdefghijk| - * | abcdefghijk| (1) Move-resize bigger - * | abcdefghijk| (2) Move - * | abcdefg| (4) Resize back to the original size - * - * By using this technique, we can simulate scrolling around in a - * large virtual space without having to actually have windows that - * big; for the pixels of the window, this is all we have to do. For - * subwindows, we have to take care of one other detail - since - * coordinates in X are limited to 16 bits, subwindows scrolled off - * will wrap around and come back eventually. So, we have to take care - * to unmap windows that go outside the 16-bit range and remap them as - * they come back in. - * - * Since we are temporarily making the window bigger, this only looks - * good if the edges of the window are obscured. Typically, we do - * this by making the window we are scrolling the immediate child - * of a "clip window". - * - * But, this isn't a perfect API for applications for several reasons: - * - * - We have to use this inefficient technique even for small windows - * if the window _could_ be big. - * - Applications have to use a special scrolling API. - * - * What we'd like is to simply have windows with 32 bit coordinates - * so applications could scroll in the classic way - just move a big - * window around. - * - * It turns out that StaticGravity can also be used to achieve emulation - * of 32 bit coordinates with only 16 bit coordinates if we expand - * our horizons just a bit; what guffaw scrolling really is is a way - * to move the contents of a window a different amount than we move - * the borders of of the window. In the above example pictures we - * ended up with the borders of the window not moving at all, but - * that isn't necessary. - * - * So, what we do is set up a mapping from virtual 32 bit window position/size - * to: - * - * - Real window position/size - * - Offset between virtual coordinates and real coordinates for the window - * - Map state (mapped or unmapped) - * - * By the following rules: - * - * - If the window is less than 32767 pixels in width (resp. height), we use it's - * virtual width and position. - * - Otherwise, we use a width of 32767 and determine the position of the window - * so that the portion of the real window [16384, 16383] in _toplevel window - * coordinates_ is the same as the portion of the real window - * - * This is implemented in gdk_window_compute_position(). Then the algorithm - * for a moving a window (_window_move_resize_child ()) is: - * - * - Compute the new window mappings for the window and all subwindows - * - Expand out the boundary of the window and all subwindows by the amount - * that the real/virtual offset changes for each window. - * (compute_intermediate_position() computes expanded boundary) - * - Move the toplevel by the amount that it's contents need to translate. - * - Move/resize the window and all subwindows to the newly computed - * positions. - * - * If we just are scrolling (gdk_window_guffaw_scroll()), then things - * are similar, except that the final mappings for the toplevel are - * the same as the initial mappings, but we act as if it moved by the - * amount we are scrolling by. - * - * Note that we don't have to worry about a clip window in - * _gdk_window_move_resize() since we have set up our translation so - * that things in the range [16384,16383] in toplevel window - * coordinates look exactly as they would if we were simply moving the - * windows, and nothing outside this range is going to be visible - * unless the user has a _really_ huge screen. - */ - #include "config.h" #include "gdk.h" /* For gdk_rectangle_intersect */ #include "gdkprivate-x11.h" @@ -165,417 +53,6 @@ struct _GdkWindowQueueItem } u; }; -struct _GdkWindowParentPos -{ - gint x; - gint y; - gint x11_x; - gint x11_y; - GdkRectangle clip_rect; -}; - -static void gdk_window_compute_position (GdkWindowImplX11 *window, - GdkWindowParentPos *parent_pos, - GdkXPositionInfo *info); -static void gdk_window_compute_parent_pos (GdkWindowImplX11 *window, - GdkWindowParentPos *parent_pos); -static void gdk_window_premove (GdkWindow *window, - GdkWindowParentPos *parent_pos); -static void gdk_window_postmove (GdkWindow *window, - GdkWindowParentPos *parent_pos); -static void gdk_window_queue_translation (GdkWindow *window, - GdkRegion *area, - gint dx, - gint dy); -static void gdk_window_clip_changed (GdkWindow *window, - GdkRectangle *old_clip, - GdkRectangle *new_clip); - -void -_gdk_x11_window_get_offsets (GdkWindow *window, - gint *x_offset, - gint *y_offset) -{ - GdkWindowImplX11 *impl = - GDK_WINDOW_IMPL_X11 (GDK_WINDOW_OBJECT (window)->impl); - - *x_offset = impl->position_info.x_offset; - *y_offset = impl->position_info.y_offset; -} - -void -_gdk_window_init_position (GdkWindow *window) -{ - GdkWindowParentPos parent_pos; - GdkWindowImplX11 *impl; - - g_return_if_fail (GDK_IS_WINDOW (window)); - - impl = - GDK_WINDOW_IMPL_X11 (GDK_WINDOW_OBJECT (window)->impl); - - gdk_window_compute_parent_pos (impl, &parent_pos); - gdk_window_compute_position (impl, &parent_pos, &impl->position_info); -} - -static void -gdk_window_copy_area_scroll (GdkWindow *window, - GdkRectangle *dest_rect, - gint dx, - gint dy) -{ - GdkWindowObject *obj = GDK_WINDOW_OBJECT (window); - GList *l; - - if (dest_rect->width > 0 && dest_rect->height > 0) - { - GdkGC *gc; - - gc = _gdk_drawable_get_scratch_gc (window, TRUE); - - gdk_window_queue_translation (window, NULL, dx, dy); - - XCopyArea (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XID (window), - GDK_WINDOW_XID (window), - gdk_x11_gc_get_xgc (gc), - dest_rect->x - dx, dest_rect->y - dy, - dest_rect->width, dest_rect->height, - dest_rect->x, dest_rect->y); - } - - for (l = obj->children; l; l = l->next) - { - GdkWindow *child = (GdkWindow*) l->data; - GdkWindowObject *child_obj = GDK_WINDOW_OBJECT (child); - - gdk_window_move (child, child_obj->x + dx, child_obj->y + dy); - } -} - -static void -compute_intermediate_position (GdkXPositionInfo *position_info, - GdkXPositionInfo *new_info, - gint d_xoffset, - gint d_yoffset, - GdkRectangle *new_position) -{ - gint new_x0, new_x1, new_y0, new_y1; - - /* Wrap d_xoffset, d_yoffset into [-32768,32767] range. For the - * purposes of subwindow movement, it doesn't matter if we are - * off by a factor of 65536, and if we don't do this range - * reduction, we'll end up with invalid widths. - */ - d_xoffset = (gint16)d_xoffset; - d_yoffset = (gint16)d_yoffset; - - if (d_xoffset < 0) - { - new_x0 = position_info->x + d_xoffset; - new_x1 = position_info->x + position_info->width; - } - else - { - new_x0 = position_info->x; - new_x1 = position_info->x + new_info->width + d_xoffset; - } - - new_position->x = new_x0; - new_position->width = new_x1 - new_x0; - - if (d_yoffset < 0) - { - new_y0 = position_info->y + d_yoffset; - new_y1 = position_info->y + position_info->height; - } - else - { - new_y0 = position_info->y; - new_y1 = position_info->y + new_info->height + d_yoffset; - } - - new_position->y = new_y0; - new_position->height = new_y1 - new_y0; -} - -static void -translate_pos (GdkWindowParentPos *dest, GdkWindowParentPos *src, - GdkWindowObject *obj, GdkXPositionInfo *pos_info, - gboolean set_clip) -{ - dest->x = src->x + obj->x; - dest->y = src->y + obj->y; - dest->x11_x = src->x11_x + pos_info->x; - dest->x11_y = src->x11_y + pos_info->y; - - if (set_clip) - dest->clip_rect = pos_info->clip_rect; -} - -static void -move (GdkWindow *window, GdkXPositionInfo *pos) -{ - XMoveWindow (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XID (window), pos->x, pos->y); -} - -static void -move_relative (GdkWindow *window, GdkRectangle *rect, - gint dx, gint dy) -{ - XMoveWindow (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XID (window), - rect->x + dx, rect->y + dy); -} - -static void -move_resize (GdkWindow *window, GdkRectangle *pos) -{ - XMoveResizeWindow (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XID (window), - pos->x, pos->y, pos->width, pos->height); -} - -static void -gdk_window_guffaw_scroll (GdkWindow *window, - gint dx, - gint dy) -{ - GdkWindowObject *obj = GDK_WINDOW_OBJECT (window); - GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (obj->impl); - - gint d_xoffset = -dx; - gint d_yoffset = -dy; - GdkRectangle new_position; - GdkXPositionInfo new_info; - GdkWindowParentPos parent_pos; - GList *l; - - gdk_window_compute_parent_pos (impl, &parent_pos); - gdk_window_compute_position (impl, &parent_pos, &new_info); - - translate_pos (&parent_pos, &parent_pos, obj, &new_info, TRUE); - - _gdk_x11_window_tmp_unset_bg (window, FALSE);; - - if (dx > 0 || dy > 0) - gdk_window_queue_translation (window, NULL, MAX (dx, 0), MAX (dy, 0)); - - gdk_window_set_static_gravities (window, TRUE); - - compute_intermediate_position (&impl->position_info, &new_info, d_xoffset, d_yoffset, - &new_position); - - move_resize (window, &new_position); - - for (l = obj->children; l; l = l->next) - { - GdkWindow *child = (GdkWindow*) l->data; - GdkWindowObject *child_obj = GDK_WINDOW_OBJECT (child); - - child_obj->x -= d_xoffset; - child_obj->y -= d_yoffset; - - gdk_window_premove (child, &parent_pos); - } - - move_relative (window, &new_position, -d_xoffset, -d_yoffset); - - if (dx < 0 || dy < 0) - gdk_window_queue_translation (window, NULL, MIN (dx, 0), MIN (dy, 0)); - - move_resize (window, (GdkRectangle *) &impl->position_info); - - if (impl->position_info.no_bg) - _gdk_x11_window_tmp_reset_bg (window, FALSE); - - impl->position_info = new_info; - - g_list_foreach (obj->children, (GFunc) gdk_window_postmove, &parent_pos); -} - -void -_gdk_x11_window_scroll (GdkWindow *window, - gint dx, - gint dy) -{ - gboolean can_guffaw_scroll = FALSE; - GdkRegion *invalidate_region; - GdkWindowImplX11 *impl; - GdkWindowObject *obj; - GdkRectangle src_rect, dest_rect; - - obj = GDK_WINDOW_OBJECT (window); - impl = GDK_WINDOW_IMPL_X11 (obj->impl); - - /* Move the current invalid region */ - if (obj->update_area) - gdk_region_offset (obj->update_area, dx, dy); - - /* impl->position_info.clip_rect isn't meaningful for toplevels */ - if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD) - src_rect = impl->position_info.clip_rect; - else - { - src_rect.x = 0; - src_rect.y = 0; - src_rect.width = impl->width; - src_rect.height = impl->height; - } - - invalidate_region = gdk_region_rectangle (&src_rect); - - dest_rect = src_rect; - dest_rect.x += dx; - dest_rect.y += dy; - gdk_rectangle_intersect (&dest_rect, &src_rect, &dest_rect); - - if (dest_rect.width > 0 && dest_rect.height > 0) - { - GdkRegion *tmp_region; - - tmp_region = gdk_region_rectangle (&dest_rect); - gdk_region_subtract (invalidate_region, tmp_region); - gdk_region_destroy (tmp_region); - } - - gdk_window_invalidate_region (window, invalidate_region, TRUE); - gdk_region_destroy (invalidate_region); - - /* We can guffaw scroll if we are a child window, and the parent - * does not extend beyond our edges. Otherwise, we use XCopyArea, then - * move any children later - */ - if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD) - { - GdkWindowImplX11 *parent_impl = GDK_WINDOW_IMPL_X11 (obj->parent->impl); - can_guffaw_scroll = ((dx == 0 || (obj->x <= 0 && obj->x + impl->width >= parent_impl->width)) && - (dy == 0 || (obj->y <= 0 && obj->y + impl->height >= parent_impl->height))); - } - - if (!obj->children || !can_guffaw_scroll) - gdk_window_copy_area_scroll (window, &dest_rect, dx, dy); - else - gdk_window_guffaw_scroll (window, dx, dy); -} - -void -_gdk_x11_window_move_region (GdkWindow *window, - const GdkRegion *region, - gint dx, - gint dy) -{ - GdkWindowImplX11 *impl; - GdkWindowObject *private; - GdkRegion *window_clip; - GdkRegion *src_region; - GdkRegion *brought_in; - GdkRegion *dest_region; - GdkRegion *moving_invalid_region; - GdkRectangle dest_extents; - GdkGC *gc; - - private = GDK_WINDOW_OBJECT (window); - impl = GDK_WINDOW_IMPL_X11 (private->impl); - - window_clip = gdk_region_rectangle (&impl->position_info.clip_rect); - - /* compute source regions */ - src_region = gdk_region_copy (region); - brought_in = gdk_region_copy (region); - gdk_region_intersect (src_region, window_clip); - - gdk_region_subtract (brought_in, src_region); - gdk_region_offset (brought_in, dx, dy); - - /* compute destination regions */ - dest_region = gdk_region_copy (src_region); - gdk_region_offset (dest_region, dx, dy); - gdk_region_intersect (dest_region, window_clip); - gdk_region_get_clipbox (dest_region, &dest_extents); - - gdk_region_destroy (window_clip); - - /* calculating moving part of current invalid area */ - moving_invalid_region = NULL; - if (private->update_area) - { - moving_invalid_region = gdk_region_copy (private->update_area); - gdk_region_intersect (moving_invalid_region, src_region); - gdk_region_offset (moving_invalid_region, dx, dy); - } - - /* invalidate all of the src region */ - gdk_window_invalidate_region (window, src_region, FALSE); - - /* un-invalidate destination region */ - if (private->update_area) - gdk_region_subtract (private->update_area, dest_region); - - /* invalidate moving parts of existing update area */ - if (moving_invalid_region) - { - gdk_window_invalidate_region (window, moving_invalid_region, FALSE); - gdk_region_destroy (moving_invalid_region); - } - - /* invalidate area brought in from off-screen */ - gdk_window_invalidate_region (window, brought_in, FALSE); - gdk_region_destroy (brought_in); - - /* Actually do the moving */ - gdk_window_queue_translation (window, src_region, dx, dy); - - gc = _gdk_drawable_get_scratch_gc (window, TRUE); - gdk_gc_set_clip_region (gc, dest_region); - - XCopyArea (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XID (window), - GDK_WINDOW_XID (window), - GDK_GC_XGC (gc), - dest_extents.x - dx, dest_extents.y - dy, - dest_extents.width, dest_extents.height, - dest_extents.x, dest_extents.y); - - /* Unset clip region of cached GC */ - gdk_gc_set_clip_region (gc, NULL); - - gdk_region_destroy (src_region); - gdk_region_destroy (dest_region); -} - -static void -reset_backgrounds (GdkWindow *window) -{ - GdkWindowObject *obj = (GdkWindowObject *)window; - - _gdk_x11_window_tmp_reset_bg (window, FALSE); - - if (obj->parent) - _gdk_x11_window_tmp_reset_bg ((GdkWindow *)obj->parent, FALSE); -} - -static void -map_if_needed (GdkWindow *window, GdkXPositionInfo *pos_info) -{ - GdkWindowObject *obj = (GdkWindowObject *) window; - GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (obj->impl); - - if (!impl->position_info.mapped && pos_info->mapped && GDK_WINDOW_IS_MAPPED (obj)) - XMapWindow (GDK_DRAWABLE_XDISPLAY (window), GDK_DRAWABLE_XID (window)); -} - -static void -unmap_if_needed (GdkWindow *window, GdkXPositionInfo *pos_info) -{ - GdkWindowObject *obj = (GdkWindowObject *) window; - GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (obj->impl); - - if (impl->position_info.mapped && !pos_info->mapped) - XUnmapWindow (GDK_DRAWABLE_XDISPLAY (window), GDK_DRAWABLE_XID (window)); -} - void _gdk_window_move_resize_child (GdkWindow *window, gint x, @@ -583,343 +60,42 @@ _gdk_window_move_resize_child (GdkWindow *window, gint width, gint height) { - GdkWindowImplX11 *impl; GdkWindowObject *obj; - GdkXPositionInfo new_info; - GdkWindowParentPos parent_pos; - - gint d_xoffset, d_yoffset; - gint dx, dy; - gboolean is_move; - gboolean is_resize; - GdkRectangle old_pos; - g_return_if_fail (window != NULL); - g_return_if_fail (GDK_IS_WINDOW (window)); + g_return_if_fail (GDK_IS_WINDOW (window)); - impl = GDK_WINDOW_IMPL_X11 (GDK_WINDOW_OBJECT (window)->impl); obj = GDK_WINDOW_OBJECT (window); - dx = x - obj->x; - dy = y - obj->y; - - is_move = dx != 0 || dy != 0; - is_resize = impl->width != width || impl->height != height; + if (width > 65535 || + height > 65535) + { + g_warning ("Native children wider or taller than 65535 pixels are not supported"); - if (!is_move && !is_resize) - return; - - old_pos.x = obj->x; - old_pos.y = obj->y; - old_pos.width = impl->width; - old_pos.height = impl->height; + if (width > 65535) + width = 65535; + if (height > 65535) + height = 65535; + } obj->x = x; obj->y = y; - impl->width = width; - impl->height = height; + obj->width = width; + obj->height = height; - gdk_window_compute_parent_pos (impl, &parent_pos); - gdk_window_compute_position (impl, &parent_pos, &new_info); + /* We don't really care about origin overflow, because on overflow + the window won't be visible anyway and thus it will be shaped + to nothing */ - gdk_window_clip_changed (window, &impl->position_info.clip_rect, &new_info.clip_rect); - - translate_pos (&parent_pos, &parent_pos, obj, &new_info, TRUE); - - d_xoffset = new_info.x_offset - impl->position_info.x_offset; - d_yoffset = new_info.y_offset - impl->position_info.y_offset; - - if (d_xoffset != 0 || d_yoffset != 0) - { - GdkRectangle new_position; - - gdk_window_set_static_gravities (window, TRUE); - - if (d_xoffset < 0 || d_yoffset < 0) - gdk_window_queue_translation (window, NULL, MIN (d_xoffset, 0), MIN (d_yoffset, 0)); - - compute_intermediate_position (&impl->position_info, &new_info, d_xoffset, d_yoffset, - &new_position); - - move_resize (window, &new_position); - - g_list_foreach (obj->children, (GFunc) gdk_window_premove, &parent_pos); - - move_relative (window, &new_position, dx, dy); - - if (d_xoffset > 0 || d_yoffset > 0) - gdk_window_queue_translation (window, NULL, MAX (d_xoffset, 0), MAX (d_yoffset, 0)); - - move_resize (window, (GdkRectangle *) &new_info); - - reset_backgrounds (window); - - map_if_needed (window, &new_info); - - impl->position_info = new_info; - - g_list_foreach (obj->children, (GFunc) gdk_window_postmove, &parent_pos); - } - else - { - if (is_move && is_resize) - gdk_window_set_static_gravities (window, FALSE); - - unmap_if_needed (window, &new_info); - - g_list_foreach (obj->children, (GFunc) gdk_window_premove, &parent_pos); - - if (is_resize) - move_resize (window, (GdkRectangle *) &new_info); - else - move (window, &new_info); - - g_list_foreach (obj->children, (GFunc) gdk_window_postmove, &parent_pos); - - reset_backgrounds (window); - - map_if_needed (window, &new_info); - - impl->position_info = new_info; - } - - if (GDK_WINDOW_IS_MAPPED (obj) && obj->parent && !obj->input_only) - gdk_window_invalidate_rect ((GdkWindow *)obj->parent, &old_pos, FALSE); -} - -static void -gdk_window_compute_position (GdkWindowImplX11 *window, - GdkWindowParentPos *parent_pos, - GdkXPositionInfo *info) -{ - GdkWindowObject *wrapper; - int parent_x_offset; - int parent_y_offset; - - g_return_if_fail (GDK_IS_WINDOW_IMPL_X11 (window)); - - wrapper = GDK_WINDOW_OBJECT (GDK_DRAWABLE_IMPL_X11 (window)->wrapper); - - info->big = FALSE; - - if (window->width <= 32767) - { - info->width = window->width; - info->x = parent_pos->x + wrapper->x - parent_pos->x11_x; - } - else - { - info->big = TRUE; - info->width = 32767; - if (parent_pos->x + wrapper->x < -16384) - { - if (parent_pos->x + wrapper->x + window->width < 16384) - info->x = parent_pos->x + wrapper->x + window->width - info->width - parent_pos->x11_x; - else - info->x = -16384 - parent_pos->x11_x; - } - else - info->x = parent_pos->x + wrapper->x - parent_pos->x11_x; - } - - if (window->height <= 32767) - { - info->height = window->height; - info->y = parent_pos->y + wrapper->y - parent_pos->x11_y; - } - else - { - info->big = TRUE; - info->height = 32767; - if (parent_pos->y + wrapper->y < -16384) - { - if (parent_pos->y + wrapper->y + window->height < 16384) - info->y = parent_pos->y + wrapper->y + window->height - info->height - parent_pos->x11_y; - else - info->y = -16384 - parent_pos->x11_y; - } - else - info->y = parent_pos->y + wrapper->y - parent_pos->x11_y; - } - - parent_x_offset = parent_pos->x11_x - parent_pos->x; - parent_y_offset = parent_pos->x11_y - parent_pos->y; - - info->x_offset = parent_x_offset + info->x - wrapper->x; - info->y_offset = parent_y_offset + info->y - wrapper->y; - - /* We don't considering the clipping of toplevel windows and their immediate children - * by their parents, and simply always map those windows. - */ - if (parent_pos->clip_rect.width == G_MAXINT) - info->mapped = TRUE; - /* Check if the window would wrap around into the visible space in either direction */ - else if (info->x + parent_x_offset < parent_pos->clip_rect.x + parent_pos->clip_rect.width - 65536 || - info->x + info->width + parent_x_offset > parent_pos->clip_rect.x + 65536 || - info->y + parent_y_offset < parent_pos->clip_rect.y + parent_pos->clip_rect.height - 65536 || - info->y + info->height + parent_y_offset > parent_pos->clip_rect.y + 65536) - info->mapped = FALSE; - else - info->mapped = TRUE; - - info->no_bg = FALSE; - - if (GDK_WINDOW_TYPE (wrapper) == GDK_WINDOW_CHILD) - { - info->clip_rect.x = wrapper->x; - info->clip_rect.y = wrapper->y; - info->clip_rect.width = window->width; - info->clip_rect.height = window->height; - - gdk_rectangle_intersect (&info->clip_rect, &parent_pos->clip_rect, &info->clip_rect); - - info->clip_rect.x -= wrapper->x; - info->clip_rect.y -= wrapper->y; - } - else - { - info->clip_rect.x = 0; - info->clip_rect.y = 0; - info->clip_rect.width = G_MAXINT; - info->clip_rect.height = G_MAXINT; - } -} - -static void -gdk_window_compute_parent_pos (GdkWindowImplX11 *window, - GdkWindowParentPos *parent_pos) -{ - GdkWindowObject *wrapper; - GdkWindowObject *parent; - GdkRectangle tmp_clip; - - int clip_xoffset = 0; - int clip_yoffset = 0; - - g_return_if_fail (GDK_IS_WINDOW_IMPL_X11 (window)); - - wrapper = - GDK_WINDOW_OBJECT (GDK_DRAWABLE_IMPL_X11 (window)->wrapper); - - parent_pos->x = 0; - parent_pos->y = 0; - parent_pos->x11_x = 0; - parent_pos->x11_y = 0; - - /* We take a simple approach here and simply consider toplevel - * windows not to clip their children on the right/bottom, since the - * size of toplevel windows is not directly under our - * control. Clipping only really matters when scrolling and - * generally we aren't going to be moving the immediate child of a - * toplevel beyond the bounds of that toplevel. - * - * We could go ahead and recompute the clips of toplevel windows and - * their descendents when we receive size notification, but it would - * probably not be an improvement in most cases. - */ - parent_pos->clip_rect.x = 0; - parent_pos->clip_rect.y = 0; - parent_pos->clip_rect.width = G_MAXINT; - parent_pos->clip_rect.height = G_MAXINT; - - parent = (GdkWindowObject *)wrapper->parent; - while (parent && parent->window_type == GDK_WINDOW_CHILD) - { - GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (parent->impl); - - tmp_clip.x = - clip_xoffset; - tmp_clip.y = - clip_yoffset; - tmp_clip.width = impl->width; - tmp_clip.height = impl->height; - - gdk_rectangle_intersect (&parent_pos->clip_rect, &tmp_clip, &parent_pos->clip_rect); - - translate_pos (parent_pos, parent_pos, parent, - &impl->position_info, FALSE); - - clip_xoffset += parent->x; - clip_yoffset += parent->y; - - parent = (GdkWindowObject *)parent->parent; - } -} - -static void -gdk_window_premove (GdkWindow *window, - GdkWindowParentPos *parent_pos) -{ - GdkWindowImplX11 *impl; - GdkWindowObject *obj; - GdkXPositionInfo new_info; - gint d_xoffset, d_yoffset; - GdkWindowParentPos this_pos; - - obj = (GdkWindowObject *) window; - impl = GDK_WINDOW_IMPL_X11 (obj->impl); - - gdk_window_compute_position (impl, parent_pos, &new_info); - - gdk_window_clip_changed (window, &impl->position_info.clip_rect, &new_info.clip_rect); - - translate_pos (&this_pos, parent_pos, obj, &new_info, TRUE); - - unmap_if_needed (window, &new_info); - - d_xoffset = new_info.x_offset - impl->position_info.x_offset; - d_yoffset = new_info.y_offset - impl->position_info.y_offset; - - if (d_xoffset != 0 || d_yoffset != 0) - { - GdkRectangle new_position; - - if (d_xoffset < 0 || d_yoffset < 0) - gdk_window_queue_translation (window, NULL, MIN (d_xoffset, 0), MIN (d_yoffset, 0)); - - compute_intermediate_position (&impl->position_info, &new_info, d_xoffset, d_yoffset, - &new_position); - - move_resize (window, &new_position); - } - - g_list_foreach (obj->children, (GFunc) gdk_window_premove, &this_pos); -} - -static void -gdk_window_postmove (GdkWindow *window, - GdkWindowParentPos *parent_pos) -{ - GdkWindowImplX11 *impl; - GdkWindowObject *obj; - GdkXPositionInfo new_info; - gint d_xoffset, d_yoffset; - GdkWindowParentPos this_pos; - - obj = (GdkWindowObject *) window; - impl = GDK_WINDOW_IMPL_X11 (obj->impl); - - gdk_window_compute_position (impl, parent_pos, &new_info); - - translate_pos (&this_pos, parent_pos, obj, &new_info, TRUE); - - d_xoffset = new_info.x_offset - impl->position_info.x_offset; - d_yoffset = new_info.y_offset - impl->position_info.y_offset; - - if (d_xoffset != 0 || d_yoffset != 0) - { - if (d_xoffset > 0 || d_yoffset > 0) - gdk_window_queue_translation (window, NULL, MAX (d_xoffset, 0), MAX (d_yoffset, 0)); - - move_resize (window, (GdkRectangle *) &new_info); - } - - map_if_needed (window, &new_info); - - reset_backgrounds (window); - - impl->position_info = new_info; - - g_list_foreach (obj->children, (GFunc) gdk_window_postmove, &this_pos); + _gdk_x11_window_tmp_unset_parent_bg (window); + _gdk_x11_window_tmp_unset_bg (window, TRUE); + XMoveResizeWindow (GDK_WINDOW_XDISPLAY (window), + GDK_WINDOW_XID (window), + obj->x + obj->parent->abs_x, + obj->y + obj->parent->abs_y, + width, height); + _gdk_x11_window_tmp_reset_parent_bg (window); + _gdk_x11_window_tmp_reset_bg (window, TRUE); } static Bool @@ -929,7 +105,7 @@ expose_serial_predicate (Display *xdisplay, { gulong *serial = (gulong *)arg; - if (xev->xany.type == Expose) + if (xev->xany.type == Expose || xev->xany.type == GraphicsExpose) *serial = MIN (*serial, xev->xany.serial); return False; @@ -1050,11 +226,12 @@ gdk_window_queue (GdkWindow *window, g_queue_push_tail (display_x11->translate_queue, item); } -static void -gdk_window_queue_translation (GdkWindow *window, - GdkRegion *area, - gint dx, - gint dy) +void +_gdk_x11_window_queue_translation (GdkWindow *window, + GdkGC *gc, + GdkRegion *area, + gint dx, + gint dy) { GdkWindowQueueItem *item = g_new (GdkWindowQueueItem, 1); item->type = GDK_WINDOW_QUEUE_TRANSLATE; @@ -1062,12 +239,17 @@ gdk_window_queue_translation (GdkWindow *window, item->u.translate.dx = dx; item->u.translate.dy = dy; + /* Ensure that the gc is flushed so that we get the right + serial from NextRequest in gdk_window_queue, i.e. the + the serial for the XCopyArea, not the ones from flushing + the gc. */ + _gdk_x11_gc_flush (gc); gdk_window_queue (window, item); } gboolean -_gdk_windowing_window_queue_antiexpose (GdkWindow *window, - GdkRegion *area) +_gdk_x11_window_queue_antiexpose (GdkWindow *window, + GdkRegion *area) { GdkWindowQueueItem *item = g_new (GdkWindowQueueItem, 1); item->type = GDK_WINDOW_QUEUE_ANTIEXPOSE; @@ -1083,21 +265,18 @@ _gdk_window_process_expose (GdkWindow *window, gulong serial, GdkRectangle *area) { - GdkWindowImplX11 *impl; GdkRegion *invalidate_region = gdk_region_rectangle (area); - GdkRegion *clip_region; GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window)); - impl = GDK_WINDOW_IMPL_X11 (GDK_WINDOW_OBJECT (window)->impl); if (display_x11->translate_queue) { GList *tmp_list = display_x11->translate_queue->head; - + while (tmp_list) { GdkWindowQueueItem *item = tmp_list->data; GList *next = tmp_list->next; - + /* an overflow-safe (serial < item->serial) */ if (serial - item->serial > (gulong) G_MAXLONG) { @@ -1108,7 +287,7 @@ _gdk_window_process_expose (GdkWindow *window, if (item->u.translate.area) { GdkRegion *intersection; - + intersection = gdk_region_copy (invalidate_region); gdk_region_intersect (intersection, item->u.translate.area); gdk_region_subtract (invalidate_region, intersection); @@ -1134,57 +313,10 @@ _gdk_window_process_expose (GdkWindow *window, } } - clip_region = gdk_region_rectangle (&impl->position_info.clip_rect); - gdk_region_intersect (invalidate_region, clip_region); - if (!gdk_region_empty (invalidate_region)) - gdk_window_invalidate_region (window, invalidate_region, FALSE); - + _gdk_window_invalidate_for_expose (window, invalidate_region); + gdk_region_destroy (invalidate_region); - gdk_region_destroy (clip_region); -} - -static void -gdk_window_clip_changed (GdkWindow *window, GdkRectangle *old_clip, GdkRectangle *new_clip) -{ - GdkWindowImplX11 *impl; - GdkWindowObject *obj; - GdkRegion *old_clip_region; - GdkRegion *new_clip_region; - - if (((GdkWindowObject *)window)->input_only) - return; - - obj = (GdkWindowObject *) window; - impl = GDK_WINDOW_IMPL_X11 (obj->impl); - - old_clip_region = gdk_region_rectangle (old_clip); - new_clip_region = gdk_region_rectangle (new_clip); - - /* We need to update this here because gdk_window_invalidate_region makes - * use if it (through gdk_drawable_get_visible_region - */ - impl->position_info.clip_rect = *new_clip; - - /* Trim invalid region of window to new clip rectangle - */ - if (obj->update_area) - gdk_region_intersect (obj->update_area, new_clip_region); - - /* Invalidate newly exposed portion of window - */ - gdk_region_subtract (new_clip_region, old_clip_region); - if (!gdk_region_empty (new_clip_region)) - { - _gdk_x11_window_tmp_unset_bg (window, FALSE);; - gdk_window_invalidate_region (window, new_clip_region, FALSE); - } - - if (obj->parent) - _gdk_x11_window_tmp_unset_bg ((GdkWindow *)obj->parent, FALSE); - - gdk_region_destroy (new_clip_region); - gdk_region_destroy (old_clip_region); } #define __GDK_GEOMETRY_X11_C__ diff --git a/gdk/x11/gdkinput-none.c b/gdk/x11/gdkinput-none.c index 38dc59c14f..4d21beff34 100644 --- a/gdk/x11/gdkinput-none.c +++ b/gdk/x11/gdkinput-none.c @@ -37,7 +37,7 @@ _gdk_input_init (GdkDisplay *display) _gdk_init_input_core (display); display_x11->input_devices = g_list_append (NULL, display->core_pointer); - display_x11->input_ignore_core = FALSE; + display->ignore_core_events = FALSE; } void @@ -72,16 +72,10 @@ _gdk_device_get_history (GdkDevice *device, return FALSE; } -gboolean -_gdk_input_enable_window(GdkWindow *window, GdkDevicePrivate *gdkdev) +void +_gdk_input_select_events (GdkWindow *impl_window, + GdkDevicePrivate *gdkdev) { - return TRUE; -} - -gboolean -_gdk_input_disable_window(GdkWindow *window, GdkDevicePrivate *gdkdev) -{ - return TRUE; } gboolean @@ -99,13 +93,14 @@ _gdk_input_configure_event (XConfigureEvent *xevent, } void -_gdk_input_enter_event (XCrossingEvent *xevent, - GdkWindow *window) +_gdk_input_crossing_event (GdkWindow *window, + gboolean enter) { } gint _gdk_input_grab_pointer (GdkWindow * window, + GdkWindow *native_window, gint owner_events, GdkEventMask event_mask, GdkWindow * confine_to, diff --git a/gdk/x11/gdkinput-x11.c b/gdk/x11/gdkinput-x11.c index 8faf704845..a793a4245f 100644 --- a/gdk/x11/gdkinput-x11.c +++ b/gdk/x11/gdkinput-x11.c @@ -21,7 +21,7 @@ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS * file for a list of people on the GTK+ Team. See the ChangeLog * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. */ #include "config.h" @@ -39,11 +39,15 @@ static GdkDevicePrivate *gdk_input_device_new (GdkDisplay *disp XDeviceInfo *device, gint include_core); static void gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev, - GdkInputWindow *input_window, + GdkWindow *window, gint *axis_data, gdouble *axis_out, gdouble *x_out, gdouble *y_out); +static void gdk_input_update_axes (GdkDevicePrivate *gdkdev, + gint axes_count, + gint first_axis, + gint *axis_data); static guint gdk_input_translate_state (guint state, guint device_state); @@ -64,37 +68,26 @@ _gdk_input_find_device (GdkDisplay *display, } void -_gdk_input_get_root_relative_geometry(Display *display, Window w, int *x_ret, int *y_ret, - int *width_ret, int *height_ret) +_gdk_input_get_root_relative_geometry (GdkWindow *window, + int *x_ret, int *y_ret) { - Window root, parent, child; - Window *children; - guint nchildren; + Window child; gint x,y; - guint width, height; - guint border_widthc, depthc; - - XQueryTree (display, w, &root, &parent, &children, &nchildren); - if (children) - XFree(children); - - XGetGeometry (display, w, &root, &x, &y, &width, &height, &border_widthc, &depthc); - XTranslateCoordinates (display, w, root, 0, 0, &x, &y, &child); - + XTranslateCoordinates (GDK_WINDOW_XDISPLAY (window), + GDK_WINDOW_XWINDOW (window), + GDK_WINDOW_XROOTWIN (window), + 0, 0, &x, &y, &child); + if (x_ret) *x_ret = x; if (y_ret) *y_ret = y; - if (width_ret) - *width_ret = width; - if (height_ret) - *height_ret = height; } static GdkDevicePrivate * gdk_input_device_new (GdkDisplay *display, - XDeviceInfo *device, + XDeviceInfo *device, gint include_core) { GdkDevicePrivate *gdkdev; @@ -121,18 +114,16 @@ gdk_input_device_new (GdkDisplay *display, for comparison purposes */ tmp_name = g_ascii_strdown (gdkdev->info.name, -1); - - if (!strcmp (tmp_name, "pointer")) - gdkdev->info.source = GDK_SOURCE_MOUSE; - else if (!strcmp (tmp_name, "wacom") || - !strcmp (tmp_name, "pen")) - gdkdev->info.source = GDK_SOURCE_PEN; - else if (!strcmp (tmp_name, "eraser")) + + if (strstr (tmp_name, "eraser")) gdkdev->info.source = GDK_SOURCE_ERASER; - else if (!strcmp (tmp_name, "cursor")) + else if (strstr (tmp_name, "cursor")) gdkdev->info.source = GDK_SOURCE_CURSOR; - else + else if (strstr (tmp_name, "wacom") || + strstr (tmp_name, "pen")) gdkdev->info.source = GDK_SOURCE_PEN; + else + gdkdev->info.source = GDK_SOURCE_MOUSE; g_free(tmp_name); @@ -148,10 +139,11 @@ gdk_input_device_new (GdkDisplay *display, gdkdev->info.has_cursor = 0; gdkdev->needs_update = FALSE; gdkdev->claimed = FALSE; - gdkdev->button_state = 0; + memset(gdkdev->button_state, 0, sizeof (gdkdev->button_state)); + gdkdev->button_count = 0; class = device->inputclassinfo; - for (i=0;inum_classes;i++) + for (i=0;inum_classes;i++) { switch (class->class) { case ButtonClass: @@ -160,7 +152,7 @@ gdk_input_device_new (GdkDisplay *display, { XKeyInfo *xki = (XKeyInfo *)class; /* Hack to catch XFree86 3.3.1 bug. Other devices better - * not have exactly 25 keys... + * not have exactly 25 keys... */ if ((xki->min_keycode == 8) && (xki->max_keycode == 32)) { @@ -187,10 +179,11 @@ gdk_input_device_new (GdkDisplay *display, XValuatorInfo *xvi = (XValuatorInfo *)class; gdkdev->info.num_axes = xvi->num_axes; gdkdev->axes = g_new (GdkAxisInfo, xvi->num_axes); + gdkdev->axis_data = g_new0 (gint, xvi->num_axes); gdkdev->info.axes = g_new0 (GdkDeviceAxis, xvi->num_axes); for (j=0;jnum_axes;j++) { - gdkdev->axes[j].resolution = + gdkdev->axes[j].resolution = gdkdev->axes[j].xresolution = xvi->axes[j].resolution; gdkdev->axes[j].min_value = gdkdev->axes[j].xmin_value = xvi->axes[j].min_value; @@ -211,7 +204,7 @@ gdk_input_device_new (GdkDisplay *display, gdk_device_set_axis_use (&gdkdev->info, j++, GDK_AXIS_YTILT); if (jnum_axes) gdk_device_set_axis_use (&gdkdev->info, j++, GDK_AXIS_WHEEL); - + break; } } @@ -247,20 +240,19 @@ gdk_input_device_new (GdkDisplay *display, error: g_object_unref (gdkdev); - + return NULL; } void -_gdk_input_common_find_events(GdkWindow *window, - GdkDevicePrivate *gdkdev, - gint mask, - XEventClass *classes, - int *num_classes) +_gdk_input_common_find_events (GdkDevicePrivate *gdkdev, + gint mask, + XEventClass *classes, + int *num_classes) { gint i; XEventClass class; - + i = 0; if (mask & GDK_BUTTON_PRESS_MASK) { @@ -279,49 +271,14 @@ _gdk_input_common_find_events(GdkWindow *window, if (class != 0) classes[i++] = class; } - if (mask & GDK_POINTER_MOTION_MASK) + if (mask & (GDK_POINTER_MOTION_MASK | + GDK_BUTTON1_MOTION_MASK | GDK_BUTTON2_MOTION_MASK | + GDK_BUTTON3_MOTION_MASK | GDK_BUTTON_MOTION_MASK)) { - DeviceMotionNotify (gdkdev->xdevice, gdkdev->motionnotify_type, class); + DeviceMotionNotify (gdkdev->xdevice, gdkdev->motionnotify_type, class); if (class != 0) classes[i++] = class; - } - else - if (mask & (GDK_BUTTON1_MOTION_MASK | GDK_BUTTON2_MOTION_MASK | - GDK_BUTTON3_MOTION_MASK | GDK_BUTTON_MOTION_MASK | - GDK_POINTER_MOTION_HINT_MASK)) - { - /* Make sure gdkdev->motionnotify_type is set */ - DeviceMotionNotify (gdkdev->xdevice, gdkdev->motionnotify_type, class); - } - if (mask & GDK_BUTTON1_MOTION_MASK) - { - DeviceButton1Motion (gdkdev->xdevice, 0, class); - if (class != 0) - classes[i++] = class; - } - if (mask & GDK_BUTTON2_MOTION_MASK) - { - DeviceButton2Motion (gdkdev->xdevice, 0, class); - if (class != 0) - classes[i++] = class; - } - if (mask & GDK_BUTTON3_MOTION_MASK) - { - DeviceButton3Motion (gdkdev->xdevice, 0, class); - if (class != 0) - classes[i++] = class; - } - if (mask & GDK_BUTTON_MOTION_MASK) - { - DeviceButtonMotion (gdkdev->xdevice, 0, class); - if (class != 0) - classes[i++] = class; - } - if (mask & GDK_POINTER_MOTION_HINT_MASK) - { - /* We'll get into trouble if the macros change, but at least we'll - know about it, and we avoid warnings now */ - DevicePointerMotionHint (gdkdev->xdevice, 0, class); + DeviceStateNotify (gdkdev->xdevice, gdkdev->devicestatenotify_type, class); if (class != 0) classes[i++] = class; } @@ -354,25 +311,42 @@ _gdk_input_common_find_events(GdkWindow *window, } void -_gdk_input_common_select_events(GdkWindow *window, - GdkDevicePrivate *gdkdev) +_gdk_input_select_events (GdkWindow *impl_window, + GdkDevicePrivate *gdkdev) { XEventClass classes[GDK_MAX_DEVICE_CLASSES]; gint num_classes; + guint event_mask; + GdkWindowObject *w; + GdkInputWindow *iw; + GList *l; - if (gdkdev->info.mode == GDK_MODE_DISABLED) - _gdk_input_common_find_events(window, gdkdev, 0, classes, &num_classes); - else - _gdk_input_common_find_events(window, gdkdev, - ((GdkWindowObject *)window)->extension_events, - classes, &num_classes); - - XSelectExtensionEvent (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XWINDOW (window), + event_mask = 0; + iw = ((GdkWindowObject *)impl_window)->input_window; + + if (gdkdev->info.mode != GDK_MODE_DISABLED && + iw != NULL) + { + for (l = iw->windows; l != NULL; l = l->next) + { + w = l->data; + if (gdkdev->info.has_cursor || (w->extension_events & GDK_ALL_DEVICES_MASK)) + event_mask |= w->extension_events; + } + } + event_mask &= ~GDK_ALL_DEVICES_MASK; + + if (event_mask) + event_mask |= GDK_PROXIMITY_OUT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK; + + _gdk_input_common_find_events (gdkdev, event_mask, + classes, &num_classes); + XSelectExtensionEvent (GDK_WINDOW_XDISPLAY (impl_window), + GDK_WINDOW_XWINDOW (impl_window), classes, num_classes); } -gint +gint _gdk_input_common_init (GdkDisplay *display, gint include_core) { @@ -391,7 +365,7 @@ _gdk_input_common_init (GdkDisplay *display, event_base, 15 /* Number of events */); devices = XListInputDevices(display_x11->xdisplay, &num_devices); - + for(loop=0; loop= 0 && first_axis + axes_count <= gdkdev->info.num_axes); + + for (i = 0; i < axes_count; i++) + gdkdev->axis_data[first_axis + i] = axis_data[i]; +} + static void gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev, - GdkInputWindow *input_window, + GdkWindow *window, gint *axis_data, gdouble *axis_out, gdouble *x_out, gdouble *y_out) { - GdkWindowImplX11 *impl; + GdkWindowObject *priv, *impl_window; + int i; int x_axis = 0; int y_axis = 0; - double device_width, device_height; + double device_width, device_height, x_min, y_min; double x_offset, y_offset, x_scale, y_scale; - impl = GDK_WINDOW_IMPL_X11 (((GdkWindowObject *) input_window->window)->impl); + priv = (GdkWindowObject *) window; + impl_window = (GdkWindowObject *)_gdk_window_get_impl_window (window); for (i=0; iinfo.num_axes; i++) { @@ -440,26 +429,43 @@ gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev, break; } } - - device_width = gdkdev->axes[x_axis].max_value - - gdkdev->axes[x_axis].min_value; - device_height = gdkdev->axes[y_axis].max_value - - gdkdev->axes[y_axis].min_value; - if (gdkdev->info.mode == GDK_MODE_SCREEN) + device_width = gdkdev->axes[x_axis].max_value - gdkdev->axes[x_axis].min_value; + if (device_width > 0) { - x_scale = gdk_screen_get_width (gdk_drawable_get_screen (input_window->window)) / device_width; - y_scale = gdk_screen_get_height (gdk_drawable_get_screen (input_window->window)) / device_height; + x_min = gdkdev->axes[x_axis].min_value; + } + else + { + device_width = gdk_screen_get_width (gdk_drawable_get_screen (window)); + x_min = 0; + } - x_offset = - input_window->root_x; - y_offset = - input_window->root_y; + device_height = gdkdev->axes[y_axis].max_value - gdkdev->axes[y_axis].min_value; + if (device_height > 0) + { + y_min = gdkdev->axes[y_axis].min_value; + } + else + { + device_height = gdk_screen_get_height (gdk_drawable_get_screen (window)); + y_min = 0; + } + + if (gdkdev->info.mode == GDK_MODE_SCREEN) + { + x_scale = gdk_screen_get_width (gdk_drawable_get_screen (window)) / device_width; + y_scale = gdk_screen_get_height (gdk_drawable_get_screen (window)) / device_height; + + x_offset = - impl_window->input_window->root_x - priv->abs_x; + y_offset = - impl_window->input_window->root_y - priv->abs_y; } else /* GDK_MODE_WINDOW */ { double x_resolution = gdkdev->axes[x_axis].resolution; double y_resolution = gdkdev->axes[y_axis].resolution; double device_aspect; - /* + /* * Some drivers incorrectly report the resolution of the device * as zero (in partiular linuxwacom < 0.5.3 with usb tablets). * This causes the device_aspect to become NaN and totally @@ -475,27 +481,24 @@ gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev, y_resolution = 1; } device_aspect = (device_height*y_resolution) / - (device_width*x_resolution); - if (device_aspect * impl->width >= impl->height) + (device_width*x_resolution); + if (device_aspect * priv->width >= priv->height) { /* device taller than window */ - x_scale = impl->width / device_width; - y_scale = (x_scale * x_resolution) - / y_resolution; + x_scale = priv->width / device_width; + y_scale = (x_scale * x_resolution) / y_resolution; x_offset = 0; - y_offset = -(device_height * y_scale - - impl->height)/2; + y_offset = -(device_height * y_scale - priv->height)/2; } else { /* window taller than device */ - y_scale = impl->height / device_height; - x_scale = (y_scale * y_resolution) - / x_resolution; + y_scale = priv->height / device_height; + x_scale = (y_scale * y_resolution) / x_resolution; y_offset = 0; - x_offset = - (device_width * x_scale - impl->width)/2; + x_offset = - (device_width * x_scale - priv->width)/2; } } @@ -504,14 +507,12 @@ gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev, switch (gdkdev->info.axes[i].use) { case GDK_AXIS_X: - axis_out[i] = x_offset + x_scale * (axis_data[x_axis] - - gdkdev->axes[x_axis].min_value); + axis_out[i] = x_offset + x_scale * (axis_data[x_axis] - x_min); if (x_out) *x_out = axis_out[i]; break; case GDK_AXIS_Y: - axis_out[i] = y_offset + y_scale * (axis_data[y_axis] - - gdkdev->axes[y_axis].min_value); + axis_out[i] = y_offset + y_scale * (axis_data[y_axis] - y_min); if (y_out) *y_out = axis_out[i]; break; @@ -541,35 +542,53 @@ gdk_input_translate_state(guint state, guint device_state) gboolean _gdk_input_common_other_event (GdkEvent *event, XEvent *xevent, - GdkInputWindow *input_window, + GdkWindow *window, GdkDevicePrivate *gdkdev) { + GdkWindowObject *priv, *impl_window; + GdkInputWindow *input_window; + + priv = (GdkWindowObject *) window; + impl_window = (GdkWindowObject *)_gdk_window_get_impl_window (window); + input_window = impl_window->input_window; + if ((xevent->type == gdkdev->buttonpress_type) || - (xevent->type == gdkdev->buttonrelease_type)) + (xevent->type == gdkdev->buttonrelease_type)) { XDeviceButtonEvent *xdbe = (XDeviceButtonEvent *)(xevent); + g_return_val_if_fail (xdbe->button < 256, FALSE); if (xdbe->type == gdkdev->buttonpress_type) { event->button.type = GDK_BUTTON_PRESS; - gdkdev->button_state |= 1 << xdbe->button; + if (!(gdkdev->button_state[xdbe->button/8] & 1 << (xdbe->button%8))) + { + gdkdev->button_state[xdbe->button/8] |= 1 << (xdbe->button%8); + gdkdev->button_count++; + } } else { event->button.type = GDK_BUTTON_RELEASE; - gdkdev->button_state &= ~(1 << xdbe->button); + if (gdkdev->button_state[xdbe->button/8] & 1 << (xdbe->button%8)) + { + gdkdev->button_state[xdbe->button/8] &= ~(1 << (xdbe->button%8)); + gdkdev->button_count--; + } } event->button.device = &gdkdev->info; - event->button.window = input_window->window; + event->button.window = window; event->button.time = xdbe->time; event->button.axes = g_new (gdouble, gdkdev->info.num_axes); - gdk_input_translate_coordinates (gdkdev,input_window, xdbe->axis_data, - event->button.axes, - &event->button.x,&event->button.y); - event->button.x_root = event->button.x + input_window->root_x; - event->button.y_root = event->button.y + input_window->root_y; - event->button.state = gdk_input_translate_state(xdbe->state,xdbe->device_state); + gdk_input_update_axes (gdkdev, xdbe->axes_count, xdbe->first_axis, + xdbe->axis_data); + gdk_input_translate_coordinates (gdkdev, window, gdkdev->axis_data, + event->button.axes, + &event->button.x, &event->button.y); + event->button.x_root = event->button.x + priv->abs_x + input_window->root_x; + event->button.y_root = event->button.y + priv->abs_y + input_window->root_y; + event->button.state = gdk_input_translate_state (xdbe->state,xdbe->device_state); event->button.button = xdbe->button; if (event->button.type == GDK_BUTTON_PRESS) @@ -588,8 +607,8 @@ _gdk_input_common_other_event (GdkEvent *event, * a valid timestamp. */ if (gdk_event_get_time (event) != GDK_CURRENT_TIME) - gdk_x11_window_set_user_time (gdk_window_get_toplevel (input_window->window), - gdk_event_get_time (event)); + gdk_x11_window_set_user_time (gdk_window_get_toplevel (window), + gdk_event_get_time (event)); return TRUE; } @@ -611,21 +630,21 @@ _gdk_input_common_other_event (GdkEvent *event, g_warning ("Invalid device key code received"); return FALSE; } - + event->key.keyval = gdkdev->info.keys[xdke->keycode - gdkdev->min_keycode].keyval; - if (event->key.keyval == 0) + if (event->key.keyval == 0) { GDK_NOTE (EVENTS, g_print ("\t\ttranslation - NONE\n")); - + return FALSE; } event->key.type = (xdke->type == gdkdev->keypress_type) ? GDK_KEY_PRESS : GDK_KEY_RELEASE; - event->key.window = input_window->window; + event->key.window = window; event->key.time = xdke->time; event->key.state = gdk_input_translate_state(xdke->state, xdke->device_state) @@ -654,26 +673,27 @@ _gdk_input_common_other_event (GdkEvent *event, * a valid timestamp. */ if (gdk_event_get_time (event) != GDK_CURRENT_TIME) - gdk_x11_window_set_user_time (gdk_window_get_toplevel (input_window->window), - gdk_event_get_time (event)); + gdk_x11_window_set_user_time (gdk_window_get_toplevel (window), + gdk_event_get_time (event)); return TRUE; } - if (xevent->type == gdkdev->motionnotify_type) + if (xevent->type == gdkdev->motionnotify_type) { XDeviceMotionEvent *xdme = (XDeviceMotionEvent *)(xevent); event->motion.device = &gdkdev->info; - + event->motion.axes = g_new (gdouble, gdkdev->info.num_axes); - gdk_input_translate_coordinates(gdkdev,input_window,xdme->axis_data, + gdk_input_update_axes (gdkdev, xdme->axes_count, xdme->first_axis, xdme->axis_data); + gdk_input_translate_coordinates(gdkdev, window, gdkdev->axis_data, event->motion.axes, &event->motion.x,&event->motion.y); - event->motion.x_root = event->motion.x + input_window->root_x; - event->motion.y_root = event->motion.y + input_window->root_y; + event->motion.x_root = event->motion.x + priv->abs_x + input_window->root_x; + event->motion.y_root = event->motion.y + priv->abs_y + input_window->root_y; event->motion.type = GDK_MOTION_NOTIFY; - event->motion.window = input_window->window; + event->motion.window = window; event->motion.time = xdme->time; event->motion.state = gdk_input_translate_state(xdme->state, xdme->device_state); @@ -686,17 +706,37 @@ _gdk_input_common_other_event (GdkEvent *event, event->motion.x, event->motion.y, event->motion.state, (xdme->is_hint) ? "true" : "false")); - - + + /* Update the timestamp of the latest user interaction, if the event has * a valid timestamp. */ if (gdk_event_get_time (event) != GDK_CURRENT_TIME) - gdk_x11_window_set_user_time (gdk_window_get_toplevel (input_window->window), - gdk_event_get_time (event)); + gdk_x11_window_set_user_time (gdk_window_get_toplevel (window), + gdk_event_get_time (event)); return TRUE; } + if (xevent->type == gdkdev->devicestatenotify_type) + { + int i; + XDeviceStateNotifyEvent *xdse = (XDeviceStateNotifyEvent *)(xevent); + XInputClass *input_class = (XInputClass *)xdse->data; + for (i=0; inum_classes; i++) + { + if (input_class->class == ValuatorClass) + gdk_input_update_axes (gdkdev, gdkdev->info.num_axes, 0, + ((XValuatorState *)input_class)->valuators); + input_class = (XInputClass *)(((char *)input_class)+input_class->length); + } + + GDK_NOTE (EVENTS, + g_print ("device state notify:\t\twindow: %ld device: %ld\n", + xdse->window, + xdse->deviceid)); + + return FALSE; + } if (xevent->type == gdkdev->proximityin_type || xevent->type == gdkdev->proximityout_type) { @@ -704,22 +744,71 @@ _gdk_input_common_other_event (GdkEvent *event, event->proximity.device = &gdkdev->info; event->proximity.type = (xevent->type == gdkdev->proximityin_type)? - GDK_PROXIMITY_IN:GDK_PROXIMITY_OUT; - event->proximity.window = input_window->window; + GDK_PROXIMITY_IN:GDK_PROXIMITY_OUT; + event->proximity.window = window; event->proximity.time = xpne->time; - + /* Update the timestamp of the latest user interaction, if the event has * a valid timestamp. */ if (gdk_event_get_time (event) != GDK_CURRENT_TIME) - gdk_x11_window_set_user_time (gdk_window_get_toplevel (input_window->window), - gdk_event_get_time (event)); + gdk_x11_window_set_user_time (gdk_window_get_toplevel (window), + gdk_event_get_time (event)); return TRUE; } return FALSE; /* wasn't one of our event types */ } +gboolean +_gdk_input_common_event_selected (GdkEvent *event, + GdkWindow *window, + GdkDevicePrivate *gdkdev) +{ + GdkWindowObject *priv = (GdkWindowObject *) window; + + switch (event->type) { + case GDK_BUTTON_PRESS: + return priv->extension_events & GDK_BUTTON_PRESS_MASK; + + case GDK_BUTTON_RELEASE: + return priv->extension_events & GDK_BUTTON_RELEASE_MASK; + + case GDK_KEY_PRESS: + return priv->extension_events & GDK_KEY_PRESS_MASK; + + case GDK_KEY_RELEASE: + return priv->extension_events & GDK_KEY_RELEASE_MASK; + + case GDK_MOTION_NOTIFY: + if (priv->extension_events & GDK_POINTER_MOTION_MASK) + return TRUE; + if (gdkdev->button_count && (priv->extension_events & GDK_BUTTON_MOTION_MASK)) + return TRUE; + + if ((gdkdev->button_state[0] & 1 << 1) && (priv->extension_events & GDK_BUTTON1_MOTION_MASK)) + return TRUE; + if ((gdkdev->button_state[0] & 1 << 2) && (priv->extension_events & GDK_BUTTON2_MOTION_MASK)) + return TRUE; + if ((gdkdev->button_state[0] & 1 << 3) && (priv->extension_events & GDK_BUTTON3_MOTION_MASK)) + return TRUE; + + return FALSE; + + case GDK_PROXIMITY_IN: + return priv->extension_events & GDK_PROXIMITY_IN_MASK; + + case GDK_PROXIMITY_OUT: + return priv->extension_events & GDK_PROXIMITY_OUT_MASK; + + default: + return FALSE; + } + + +} + + gboolean _gdk_device_get_history (GdkDevice *device, GdkWindow *window, @@ -730,18 +819,17 @@ _gdk_device_get_history (GdkDevice *device, { GdkTimeCoord **coords; XDeviceTimeCoord *device_coords; - GdkInputWindow *input_window; + GdkWindow *impl_window; GdkDevicePrivate *gdkdev; gint mode_return; gint axis_count_return; gint i; gdkdev = (GdkDevicePrivate *)device; - input_window = _gdk_input_window_find (window); - g_return_val_if_fail (input_window != NULL, FALSE); + impl_window = _gdk_window_get_impl_window (window); - device_coords = XGetDeviceMotionEvents (GDK_WINDOW_XDISPLAY (window), + device_coords = XGetDeviceMotionEvents (GDK_WINDOW_XDISPLAY (impl_window), gdkdev->xdevice, start, stop, n_events, &mode_return, @@ -752,13 +840,13 @@ _gdk_device_get_history (GdkDevice *device, coords = _gdk_device_allocate_history (device, *n_events); for (i = 0; i < *n_events; i++) - { - coords[i]->time = device_coords[i].time; + { + coords[i]->time = device_coords[i].time; - gdk_input_translate_coordinates (gdkdev, input_window, - device_coords[i].data, - coords[i]->axes, NULL, NULL); - } + gdk_input_translate_coordinates (gdkdev, window, + device_coords[i].data, + coords[i]->axes, NULL, NULL); + } XFreeDeviceMotionEvents (device_coords); @@ -770,7 +858,7 @@ _gdk_device_get_history (GdkDevice *device, return FALSE; } -void +void gdk_device_get_state (GdkDevice *device, GdkWindow *window, gdouble *axes, @@ -784,7 +872,7 @@ gdk_device_get_state (GdkDevice *device, if (GDK_IS_CORE (device)) { gint x_int, y_int; - + gdk_window_get_pointer (window, &x_int, &y_int, mask); if (axes) @@ -796,16 +884,13 @@ gdk_device_get_state (GdkDevice *device, else { GdkDevicePrivate *gdkdev; - GdkInputWindow *input_window; XDeviceState *state; XInputClass *input_class; - + if (mask) gdk_window_get_pointer (window, NULL, NULL, mask); - + gdkdev = (GdkDevicePrivate *)device; - input_window = _gdk_input_window_find (window); - g_return_if_fail (input_window != NULL); state = XQueryDeviceState (GDK_WINDOW_XDISPLAY (window), gdkdev->xdevice); @@ -816,11 +901,11 @@ gdk_device_get_state (GdkDevice *device, { case ValuatorClass: if (axes) - gdk_input_translate_coordinates (gdkdev, input_window, + gdk_input_translate_coordinates (gdkdev, window, ((XValuatorState *)input_class)->valuators, axes, NULL, NULL); break; - + case ButtonClass: if (mask) { diff --git a/gdk/x11/gdkinput-xfree.c b/gdk/x11/gdkinput-xfree.c index b51516b3e1..d0f217c86e 100644 --- a/gdk/x11/gdkinput-xfree.c +++ b/gdk/x11/gdkinput-xfree.c @@ -26,18 +26,18 @@ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS * file for a list of people on the GTK+ Team. See the ChangeLog * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. */ /* forward declarations */ static void gdk_input_check_proximity (GdkDisplay *display); -void +void _gdk_input_init(GdkDisplay *display) { _gdk_init_input_core (display); - GDK_DISPLAY_X11 (display)->input_ignore_core = FALSE; + display->ignore_core_events = FALSE; _gdk_input_common_init (display, FALSE); } @@ -47,7 +47,6 @@ gdk_device_set_mode (GdkDevice *device, { GList *tmp_list; GdkDevicePrivate *gdkdev; - GdkInputMode old_mode; GdkInputWindow *input_window; GdkDisplayX11 *display_impl; @@ -59,58 +58,35 @@ gdk_device_set_mode (GdkDevice *device, if (device->mode == mode) return TRUE; - old_mode = device->mode; device->mode = mode; - display_impl = GDK_DISPLAY_X11 (gdkdev->display); - if (mode == GDK_MODE_WINDOW) - { - device->has_cursor = FALSE; - for (tmp_list = display_impl->input_windows; tmp_list; tmp_list = tmp_list->next) - { - input_window = (GdkInputWindow *)tmp_list->data; - if (input_window->mode != GDK_EXTENSION_EVENTS_CURSOR) - _gdk_input_enable_window (input_window->window, gdkdev); - else - if (old_mode != GDK_MODE_DISABLED) - _gdk_input_disable_window (input_window->window, gdkdev); - } - } + device->has_cursor = FALSE; else if (mode == GDK_MODE_SCREEN) + device->has_cursor = TRUE; + + display_impl = GDK_DISPLAY_X11 (gdkdev->display); + for (tmp_list = display_impl->input_windows; tmp_list; tmp_list = tmp_list->next) { - device->has_cursor = TRUE; - for (tmp_list = display_impl->input_windows; tmp_list; tmp_list = tmp_list->next) - _gdk_input_enable_window (((GdkInputWindow *)tmp_list->data)->window, - gdkdev); - } - else /* mode == GDK_MODE_DISABLED */ - { - for (tmp_list = display_impl->input_windows; tmp_list; tmp_list = tmp_list->next) - { - input_window = (GdkInputWindow *)tmp_list->data; - if (old_mode != GDK_MODE_WINDOW || - input_window->mode != GDK_EXTENSION_EVENTS_CURSOR) - _gdk_input_disable_window (input_window->window, gdkdev); - } + input_window = (GdkInputWindow *)tmp_list->data; + _gdk_input_select_events (input_window->impl_window, gdkdev); } return TRUE; - } static void gdk_input_check_proximity (GdkDisplay *display) { - gint new_proximity = 0; GdkDisplayX11 *display_impl = GDK_DISPLAY_X11 (display); GList *tmp_list = display_impl->input_devices; + gint new_proximity = 0; - while (tmp_list && !new_proximity) + while (tmp_list && !new_proximity) { GdkDevicePrivate *gdkdev = (GdkDevicePrivate *)(tmp_list->data); - if (gdkdev->info.mode != GDK_MODE_DISABLED + if (gdkdev->info.mode != GDK_MODE_DISABLED && !GDK_IS_CORE (gdkdev) && gdkdev->xdevice) { @@ -118,7 +94,7 @@ gdk_input_check_proximity (GdkDisplay *display) gdkdev->xdevice); XInputClass *xic; int i; - + xic = state->data; for (i=0; inum_classes; i++) { @@ -135,117 +111,199 @@ gdk_input_check_proximity (GdkDisplay *display) } XFreeDeviceState (state); - } + } tmp_list = tmp_list->next; } - display_impl->input_ignore_core = new_proximity; + display->ignore_core_events = new_proximity; } void _gdk_input_configure_event (XConfigureEvent *xevent, GdkWindow *window) { + GdkWindowObject *priv = (GdkWindowObject *)window; GdkInputWindow *input_window; gint root_x, root_y; - input_window = _gdk_input_window_find(window); - g_return_if_fail (input_window != NULL); - - _gdk_input_get_root_relative_geometry(GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XWINDOW (window), - &root_x, &root_y, NULL, NULL); - - input_window->root_x = root_x; - input_window->root_y = root_y; + input_window = priv->input_window; + if (input_window != NULL) + { + _gdk_input_get_root_relative_geometry (window, &root_x, &root_y); + input_window->root_x = root_x; + input_window->root_y = root_y; + } } -void -_gdk_input_enter_event (XCrossingEvent *xevent, - GdkWindow *window) +void +_gdk_input_crossing_event (GdkWindow *window, + gboolean enter) { + GdkDisplay *display = GDK_WINDOW_DISPLAY (window); + GdkDisplayX11 *display_impl = GDK_DISPLAY_X11 (display); + GdkWindowObject *priv = (GdkWindowObject *)window; GdkInputWindow *input_window; gint root_x, root_y; - input_window = _gdk_input_window_find (window); - g_return_if_fail (input_window != NULL); + if (enter) + { + gdk_input_check_proximity(display); - gdk_input_check_proximity(GDK_WINDOW_DISPLAY (window)); - - _gdk_input_get_root_relative_geometry(GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XWINDOW(window), - &root_x, &root_y, NULL, NULL); - - input_window->root_x = root_x; - input_window->root_y = root_y; + input_window = priv->input_window; + if (input_window != NULL) + { + _gdk_input_get_root_relative_geometry (window, &root_x, &root_y); + input_window->root_x = root_x; + input_window->root_y = root_y; + } + } + else + display->ignore_core_events = FALSE; } -gboolean -_gdk_input_other_event (GdkEvent *event, - XEvent *xevent, - GdkWindow *window) +static GdkEventType +get_input_event_type (GdkDevicePrivate *gdkdev, + XEvent *xevent, + int *core_x, int *core_y) { - GdkInputWindow *input_window; - + if (xevent->type == gdkdev->buttonpress_type) + { + XDeviceButtonEvent *xie = (XDeviceButtonEvent *)(xevent); + *core_x = xie->x; + *core_y = xie->y; + return GDK_BUTTON_PRESS; + } + + if (xevent->type == gdkdev->buttonrelease_type) + { + XDeviceButtonEvent *xie = (XDeviceButtonEvent *)(xevent); + *core_x = xie->x; + *core_y = xie->y; + return GDK_BUTTON_RELEASE; + } + + if (xevent->type == gdkdev->keypress_type) + { + XDeviceKeyEvent *xie = (XDeviceKeyEvent *)(xevent); + *core_x = xie->x; + *core_y = xie->y; + return GDK_KEY_PRESS; + } + + if (xevent->type == gdkdev->keyrelease_type) + { + XDeviceKeyEvent *xie = (XDeviceKeyEvent *)(xevent); + *core_x = xie->x; + *core_y = xie->y; + return GDK_KEY_RELEASE; + } + + if (xevent->type == gdkdev->motionnotify_type) + { + XDeviceMotionEvent *xie = (XDeviceMotionEvent *)(xevent); + *core_x = xie->x; + *core_y = xie->y; + return GDK_MOTION_NOTIFY; + } + + if (xevent->type == gdkdev->proximityin_type) + { + XProximityNotifyEvent *xie = (XProximityNotifyEvent *)(xevent); + *core_x = xie->x; + *core_y = xie->y; + return GDK_PROXIMITY_IN; + } + + if (xevent->type == gdkdev->proximityout_type) + { + XProximityNotifyEvent *xie = (XProximityNotifyEvent *)(xevent); + *core_x = xie->x; + *core_y = xie->y; + return GDK_PROXIMITY_OUT; + } + + *core_x = 0; + *core_y = 0; + return GDK_NOTHING; +} + + +gboolean +_gdk_input_other_event (GdkEvent *event, + XEvent *xevent, + GdkWindow *event_window) +{ + GdkWindow *window; + GdkWindowObject *priv; + GdkInputWindow *iw; GdkDevicePrivate *gdkdev; - gint return_val; - GdkDisplayX11 *display_impl = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window)); - - input_window = _gdk_input_window_find(window); - g_return_val_if_fail (input_window != NULL, FALSE); + GdkEventType event_type; + int x, y; + GdkDisplay *display = GDK_WINDOW_DISPLAY (event_window); + GdkDisplayX11 *display_impl = GDK_DISPLAY_X11 (display); /* This is a sort of a hack, as there isn't any XDeviceAnyEvent - but it's potentially faster than scanning through the types of every device. If we were deceived, then it won't match any of the types for the device anyways */ - gdkdev = _gdk_input_find_device (GDK_WINDOW_DISPLAY (window), + gdkdev = _gdk_input_find_device (display, ((XDeviceButtonEvent *)xevent)->deviceid); if (!gdkdev) return FALSE; /* we don't handle it - not an XInput event */ - /* FIXME: It would be nice if we could just get rid of the events - entirely, instead of having to ignore them */ - if (gdkdev->info.mode == GDK_MODE_DISABLED || - (gdkdev->info.mode == GDK_MODE_WINDOW - && input_window->mode == GDK_EXTENSION_EVENTS_CURSOR)) + event_type = get_input_event_type (gdkdev, xevent, &x, &y); + if (event_type == GDK_NOTHING) return FALSE; - - if (!display_impl->input_ignore_core) - gdk_input_check_proximity(GDK_WINDOW_DISPLAY (window)); - return_val = _gdk_input_common_other_event (event, xevent, - input_window, gdkdev); + /* If we're not getting any event window its likely because we're outside the + window and there is no grab. We should still report according to the + implicit grab though. */ + iw = ((GdkWindowObject *)event_window)->input_window; - if (return_val && event->type == GDK_PROXIMITY_OUT && - display_impl->input_ignore_core) - gdk_input_check_proximity(GDK_WINDOW_DISPLAY (window)); + if (iw->button_down_window) + window = iw->button_down_window; + else + window = _gdk_window_get_input_window_for_event (event_window, + event_type, + x, y, + xevent->xany.serial); + priv = (GdkWindowObject *)window; + if (window == NULL) + return FALSE; - return return_val; + if (gdkdev->info.mode == GDK_MODE_DISABLED || + priv->extension_events == 0 || + !(gdkdev->info.has_cursor || (priv->extension_events & GDK_ALL_DEVICES_MASK))) + return FALSE; + + if (!display->ignore_core_events && priv->extension_events != 0) + gdk_input_check_proximity (GDK_WINDOW_DISPLAY (window)); + + if (!_gdk_input_common_other_event (event, xevent, window, gdkdev)) + return FALSE; + + if (event->type == GDK_BUTTON_PRESS) + iw->button_down_window = window; + if (event->type == GDK_BUTTON_RELEASE && !gdkdev->button_count) + iw->button_down_window = NULL; + + if (event->type == GDK_PROXIMITY_OUT && + display->ignore_core_events) + gdk_input_check_proximity (GDK_WINDOW_DISPLAY (window)); + + return _gdk_input_common_event_selected(event, window, gdkdev); } -gboolean -_gdk_input_enable_window(GdkWindow *window, GdkDevicePrivate *gdkdev) -{ - /* FIXME: watchout, gdkdev might be core pointer, never opened */ - _gdk_input_common_select_events (window, gdkdev); - return TRUE; -} - -gboolean -_gdk_input_disable_window(GdkWindow *window, GdkDevicePrivate *gdkdev) -{ - _gdk_input_common_select_events (window, gdkdev); - return TRUE; -} - -gint -_gdk_input_grab_pointer (GdkWindow * window, +gint +_gdk_input_grab_pointer (GdkWindow *window, + GdkWindow *native_window, /* This is the toplevel */ gint owner_events, GdkEventMask event_mask, GdkWindow * confine_to, guint32 time) { - GdkInputWindow *input_window, *new_window; + GdkInputWindow *input_window; + GdkWindowObject *priv, *impl_window; gboolean need_ungrab; GdkDevicePrivate *gdkdev; GList *tmp_list; @@ -255,36 +313,36 @@ _gdk_input_grab_pointer (GdkWindow * window, GdkDisplayX11 *display_impl = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window)); tmp_list = display_impl->input_windows; - new_window = NULL; need_ungrab = FALSE; while (tmp_list) { input_window = (GdkInputWindow *)tmp_list->data; - if (input_window->window == window) - new_window = input_window; - else if (input_window->grabbed) + if (input_window->grabbed) { input_window->grabbed = FALSE; need_ungrab = TRUE; + break; } - tmp_list = tmp_list->next; } - if (new_window) + priv = (GdkWindowObject *)window; + impl_window = (GdkWindowObject *)_gdk_window_get_impl_window (window); + input_window = impl_window->input_window; + if (priv->extension_events) { - new_window->grabbed = TRUE; - + g_assert (input_window != NULL); + input_window->grabbed = TRUE; + tmp_list = display_impl->input_devices; while (tmp_list) { gdkdev = (GdkDevicePrivate *)tmp_list->data; if (!GDK_IS_CORE (gdkdev) && gdkdev->xdevice) { - _gdk_input_common_find_events (window, gdkdev, - event_mask, + _gdk_input_common_find_events (gdkdev, event_mask, event_classes, &num_classes); #ifdef G_ENABLE_DEBUG if (_gdk_debug_flags & GDK_DEBUG_NOGRABS) @@ -292,10 +350,10 @@ _gdk_input_grab_pointer (GdkWindow * window, else #endif result = XGrabDevice (display_impl->xdisplay, gdkdev->xdevice, - GDK_WINDOW_XWINDOW (window), + GDK_WINDOW_XWINDOW (native_window), owner_events, num_classes, event_classes, GrabModeAsync, GrabModeAsync, time); - + /* FIXME: if failure occurs on something other than the first device, things will be badly inconsistent */ if (result != Success) @@ -305,28 +363,28 @@ _gdk_input_grab_pointer (GdkWindow * window, } } else - { + { tmp_list = display_impl->input_devices; while (tmp_list) { gdkdev = (GdkDevicePrivate *)tmp_list->data; if (!GDK_IS_CORE (gdkdev) && gdkdev->xdevice && - ((gdkdev->button_state != 0) || need_ungrab)) + ((gdkdev->button_count != 0) || need_ungrab)) { XUngrabDevice (display_impl->xdisplay, gdkdev->xdevice, time); - gdkdev->button_state = 0; + memset(gdkdev->button_state, 0, sizeof (gdkdev->button_state)); + gdkdev->button_count = 0; } - + tmp_list = tmp_list->next; } } return Success; - } -void -_gdk_input_ungrab_pointer (GdkDisplay *display, +void +_gdk_input_ungrab_pointer (GdkDisplay *display, guint32 time) { GdkInputWindow *input_window = NULL; /* Quiet GCC */ diff --git a/gdk/x11/gdkinput.c b/gdk/x11/gdkinput.c index 0d48e13f3b..25f93dc28d 100644 --- a/gdk/x11/gdkinput.c +++ b/gdk/x11/gdkinput.c @@ -21,7 +21,7 @@ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS * file for a list of people on the GTK+ Team. See the ChangeLog * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. */ #include "config.h" @@ -47,10 +47,10 @@ void _gdk_init_input_core (GdkDisplay *display) { GdkDevicePrivate *private; - + display->core_pointer = g_object_new (GDK_TYPE_DEVICE, NULL); private = (GdkDevicePrivate *)display->core_pointer; - + display->core_pointer->name = "Core Pointer"; display->core_pointer->source = GDK_SOURCE_MOUSE; display->core_pointer->mode = GDK_MODE_SCREEN; @@ -87,12 +87,12 @@ gdk_device_get_type (void) 0, /* n_preallocs */ (GInstanceInitFunc) NULL, }; - + object_type = g_type_register_static (G_TYPE_OBJECT, - g_intern_static_string ("GdkDevice"), - &object_info, 0); + g_intern_static_string ("GdkDevice"), + &object_info, 0); } - + return object_type; } @@ -115,12 +115,14 @@ gdk_device_dispose (GObject *object) { #ifndef XINPUT_NONE if (gdkdev->xdevice) - { - XCloseDevice (GDK_DISPLAY_XDISPLAY (gdkdev->display), gdkdev->xdevice); - gdkdev->xdevice = NULL; - } + { + XCloseDevice (GDK_DISPLAY_XDISPLAY (gdkdev->display), gdkdev->xdevice); + gdkdev->xdevice = NULL; + } g_free (gdkdev->axes); + g_free (gdkdev->axis_data); gdkdev->axes = NULL; + gdkdev->axis_data = NULL; #endif /* !XINPUT_NONE */ g_free (gdkdev->info.name); @@ -140,7 +142,7 @@ gdk_device_dispose (GObject *object) * * Returns the list of available input devices for the default display. * The list is statically allocated and should not be freed. - * + * * Return value: a list of #GdkDevice **/ GList * @@ -155,16 +157,16 @@ gdk_devices_list (void) * * Returns the list of available input devices attached to @display. * The list is statically allocated and should not be freed. - * + * * Return value: a list of #GdkDevice * * Since: 2.2 **/ -GList * +GList * gdk_display_list_devices (GdkDisplay *display) { g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); - + return GDK_DISPLAY_X11 (display)->input_devices; } @@ -219,6 +221,22 @@ gdk_device_set_axis_use (GdkDevice *device, } } +static gboolean +impl_coord_in_window (GdkWindow *window, + int impl_x, + int impl_y) +{ + GdkWindowObject *priv = (GdkWindowObject *)window; + + if (impl_x < priv->abs_x || + impl_x > priv->abs_x + priv->width) + return FALSE; + if (impl_y < priv->abs_y || + impl_y > priv->abs_y + priv->height) + return FALSE; + return TRUE; +} + /** * gdk_device_get_history: * @device: a #GdkDevice @@ -227,14 +245,14 @@ gdk_device_set_axis_use (GdkDevice *device, * @stop: ending timestamp for the range of events to return * @events: location to store a newly-allocated array of #GdkTimeCoord, or %NULL * @n_events: location to store the length of @events, or %NULL - * + * * Obtains the motion history for a device; given a starting and * ending timestamp, return all events in the motion history for * the device in the given range of time. Some windowing systems * do not support motion history, in which case, %FALSE will * be returned. (This is not distinguishable from the case where * motion history is supported and no events were found.) - * + * * Return value: %TRUE if the windowing system supports motion history and * at least one event was found. **/ @@ -247,43 +265,70 @@ gdk_device_get_history (GdkDevice *device, gint *n_events) { GdkTimeCoord **coords = NULL; + GdkWindow *impl_window; gboolean result = FALSE; int tmp_n_events = 0; - int i; - g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE); + g_return_val_if_fail (GDK_WINDOW_IS_X11 (window), FALSE); + + impl_window = _gdk_window_get_impl_window (window); if (GDK_WINDOW_DESTROYED (window)) /* Nothing */ ; else if (GDK_IS_CORE (device)) { XTimeCoord *xcoords; - + xcoords = XGetMotionEvents (GDK_DRAWABLE_XDISPLAY (window), - GDK_DRAWABLE_XID (window), + GDK_DRAWABLE_XID (impl_window), start, stop, &tmp_n_events); if (xcoords) { + GdkWindowObject *priv = (GdkWindowObject *)window; + int i, j; + coords = _gdk_device_allocate_history (device, tmp_n_events); - for (i=0; itime = xcoords[i].time; - coords[i]->axes[0] = xcoords[i].x; - coords[i]->axes[1] = xcoords[i].y; + if (impl_coord_in_window (window, xcoords[i].x, xcoords[i].y)) + { + coords[j]->time = xcoords[i].time; + coords[j]->axes[0] = xcoords[i].x - priv->abs_x; + coords[j]->axes[1] = xcoords[i].y - priv->abs_y; + j++; + } } XFree (xcoords); - result = TRUE; + /* free the events we allocated too much */ + for (i = j; i < tmp_n_events; i++) + { + g_free (coords[i]); + coords[i] = NULL; + } + + tmp_n_events = j; + + if (tmp_n_events > 0) + { + result = TRUE; + } + else + { + gdk_device_free_history (coords, tmp_n_events); + coords = NULL; + } } - else - result = FALSE; } else result = _gdk_device_get_history (device, window, start, stop, &coords, &tmp_n_events); if (n_events) *n_events = tmp_n_events; + if (events) *events = coords; else if (coords) @@ -292,7 +337,7 @@ gdk_device_get_history (GdkDevice *device, return result; } -GdkTimeCoord ** +GdkTimeCoord ** _gdk_device_allocate_history (GdkDevice *device, gint n_events) { @@ -306,100 +351,105 @@ _gdk_device_allocate_history (GdkDevice *device, return result; } -void +void gdk_device_free_history (GdkTimeCoord **events, gint n_events) { gint i; - + for (i=0; iinput_windows; tmp_list; tmp_list=tmp_list->next) - if (((GdkInputWindow *)(tmp_list->data))->window == window) - return (GdkInputWindow *)(tmp_list->data); + window_private = (GdkWindowObject*) window; + impl_window = (GdkWindowObject *)_gdk_window_get_impl_window (window); + iw = impl_window->input_window; - return NULL; /* Not found */ + display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window)); + + if (window_private->extension_events != 0) + { + g_assert (iw != NULL); + g_assert (g_list_find (iw->windows, window) != NULL); + + iw->windows = g_list_remove (iw->windows, window); + if (iw->windows == NULL) + { + impl_window->input_window = NULL; + display_x11->input_windows = g_list_remove (display_x11->input_windows, iw); + g_free (iw); + } + } + + window_private->extension_events = 0; } -/* FIXME: this routine currently needs to be called between creation - and the corresponding configure event (because it doesn't get the - root_relative_geometry). This should work with - gtk_window_set_extension_events, but will likely fail in other - cases */ - void gdk_input_set_extension_events (GdkWindow *window, gint mask, GdkExtensionMode mode) { GdkWindowObject *window_private; GList *tmp_list; + GdkWindowObject *impl_window; GdkInputWindow *iw; GdkDisplayX11 *display_x11; g_return_if_fail (window != NULL); - g_return_if_fail (GDK_IS_WINDOW (window)); + g_return_if_fail (GDK_WINDOW_IS_X11 (window)); window_private = (GdkWindowObject*) window; display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window)); if (GDK_WINDOW_DESTROYED (window)) return; + impl_window = (GdkWindowObject *)_gdk_window_get_impl_window (window); + + if (mode == GDK_EXTENSION_EVENTS_ALL && mask != 0) + mask |= GDK_ALL_DEVICES_MASK; + if (mode == GDK_EXTENSION_EVENTS_NONE) mask = 0; - iw = _gdk_input_window_find (window); + iw = impl_window->input_window; if (mask != 0) { if (!iw) - { - iw = g_new(GdkInputWindow,1); + { + iw = g_new0 (GdkInputWindow,1); - iw->window = window; - iw->mode = mode; + iw->impl_window = (GdkWindow *)impl_window; - iw->obscuring = NULL; - iw->num_obscuring = 0; - iw->grabbed = FALSE; + iw->windows = NULL; + iw->grabbed = FALSE; - display_x11->input_windows = g_list_append(display_x11->input_windows,iw); - } - - window_private->extension_events = mask; + display_x11->input_windows = g_list_append (display_x11->input_windows, iw); #ifndef XINPUT_NONE - /* Add enter window events to the event mask */ - /* this is not needed for XINPUT_NONE */ - gdk_window_set_events (window, - gdk_window_get_events (window) | - GDK_ENTER_NOTIFY_MASK); - - /* we might not receive ConfigureNotify so get the root_relative_geometry - * now, just in case */ - _gdk_input_get_root_relative_geometry (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XWINDOW (window), - &iw->root_x, &iw->root_y, NULL, NULL); + /* we might not receive ConfigureNotify so get the root_relative_geometry + * now, just in case */ + _gdk_input_get_root_relative_geometry (window, &iw->root_x, &iw->root_y); #endif /* !XINPUT_NONE */ + impl_window->input_window = iw; + } + + if (window_private->extension_events == 0) + iw->windows = g_list_append (iw->windows, window); + window_private->extension_events = mask; } else { - if (iw) - { - display_x11->input_windows = g_list_remove(display_x11->input_windows,iw); - g_free(iw); - } - - window_private->extension_events = 0; + unset_extension_events (window); } for (tmp_list = display_x11->input_devices; tmp_list; tmp_list = tmp_list->next) @@ -407,57 +457,14 @@ gdk_input_set_extension_events (GdkWindow *window, gint mask, GdkDevicePrivate *gdkdev = tmp_list->data; if (!GDK_IS_CORE (gdkdev)) - { - if (mask != 0 && gdkdev->info.mode != GDK_MODE_DISABLED - && (gdkdev->info.has_cursor || mode == GDK_EXTENSION_EVENTS_ALL)) - _gdk_input_enable_window (window,gdkdev); - else - _gdk_input_disable_window (window,gdkdev); - } + _gdk_input_select_events ((GdkWindow *)impl_window, gdkdev); } } void _gdk_input_window_destroy (GdkWindow *window) { - GdkInputWindow *input_window; - GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window)); - - input_window = _gdk_input_window_find (window); - g_return_if_fail (input_window != NULL); - - display_x11->input_windows = g_list_remove (display_x11->input_windows, input_window); - g_free(input_window); -} - -void -_gdk_input_exit (void) -{ - GList *tmp_list; - GSList *display_list; - GdkDevicePrivate *gdkdev; - - for (display_list = _gdk_displays ; display_list ; display_list = display_list->next) - { - GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display_list->data); - - for (tmp_list = display_x11->input_devices; tmp_list; tmp_list = tmp_list->next) - { - gdkdev = (GdkDevicePrivate *)(tmp_list->data); - if (!GDK_IS_CORE (gdkdev)) - { - gdk_device_set_mode (&gdkdev->info, GDK_MODE_DISABLED); - g_object_unref(gdkdev); - } - } - - g_list_free(display_x11->input_devices); - - for (tmp_list = display_x11->input_windows; tmp_list; tmp_list = tmp_list->next) - g_free(tmp_list->data); - - g_list_free(display_x11->input_windows); - } + unset_extension_events (window); } /** @@ -466,10 +473,10 @@ _gdk_input_exit (void) * @axes: pointer to an array of axes * @use: the use to look for * @value: location to store the found value. - * + * * Interprets an array of double as axis values for a given device, * and locates the value in the array for a given axis use. - * + * * Return value: %TRUE if the given axis use was found, otherwise %FALSE **/ gboolean @@ -479,12 +486,12 @@ gdk_device_get_axis (GdkDevice *device, gdouble *value) { gint i; - + g_return_val_if_fail (device != NULL, FALSE); if (axes == NULL) return FALSE; - + for (i=0; inum_axes; i++) if (device->axes[i].use == use) { @@ -492,7 +499,7 @@ gdk_device_get_axis (GdkDevice *device, *value = axes[i]; return TRUE; } - + return FALSE; } diff --git a/gdk/x11/gdkinputprivate.h b/gdk/x11/gdkinputprivate.h index 5cbd809deb..1b89230fcf 100644 --- a/gdk/x11/gdkinputprivate.h +++ b/gdk/x11/gdkinputprivate.h @@ -41,7 +41,6 @@ typedef struct _GdkAxisInfo GdkAxisInfo; typedef struct _GdkDevicePrivate GdkDevicePrivate; -typedef struct _GdkInputWindow GdkInputWindow; /* information about a device axis */ struct _GdkAxisInfo @@ -74,6 +73,7 @@ struct _GdkDevicePrivate #ifndef XINPUT_NONE /* information about the axes */ GdkAxisInfo *axes; + gint *axis_data; /* Information about XInput device */ XDevice *xdevice; @@ -83,14 +83,15 @@ struct _GdkDevicePrivate int buttonpress_type, buttonrelease_type, keypress_type, keyrelease_type, motionnotify_type, proximityin_type, - proximityout_type, changenotify_type; + proximityout_type, changenotify_type, devicestatenotify_type; /* true if we need to select a different set of events, but can't because this is the core pointer */ gint needs_update; /* Mask of buttons (used for button grabs) */ - gint button_state; + char button_state[32]; + gint button_count; /* true if we've claimed the device as active. (used only for XINPUT_GXI) */ gint claimed; @@ -102,28 +103,25 @@ struct _GdkDeviceClass GObjectClass parent_class; }; +/* Addition used for extension_events mask */ +#define GDK_ALL_DEVICES_MASK (1<<30) + struct _GdkInputWindow { - /* gdk window */ - GdkWindow *window; + GList *windows; /* GdkWindow:s with extension_events set */ - /* Extension mode (GDK_EXTENSION_EVENTS_ALL/CURSOR) */ - GdkExtensionMode mode; + /* gdk window */ + GdkWindow *impl_window; /* an impl window */ + GdkWindow *button_down_window; /* position relative to root window */ gint root_x; gint root_y; - /* rectangles relative to window of windows obscuring this one */ - GdkRectangle *obscuring; - gint num_obscuring; - /* Is there a pointer grab for this window ? */ gint grabbed; }; - - /* Global data */ #define GDK_IS_CORE(d) (((GdkDevice *)(d)) == ((GdkDevicePrivate *)(d))->display->core_pointer) @@ -139,18 +137,15 @@ void _gdk_init_input_core (GdkDisplay *display); /* The following functions are provided by each implementation * (xfree, gxi, and none) */ -gint _gdk_input_enable_window (GdkWindow *window, - GdkDevicePrivate *gdkdev); -gint _gdk_input_disable_window (GdkWindow *window, - GdkDevicePrivate *gdkdev); void _gdk_input_configure_event (XConfigureEvent *xevent, GdkWindow *window); -void _gdk_input_enter_event (XCrossingEvent *xevent, - GdkWindow *window); +void _gdk_input_crossing_event (GdkWindow *window, + gboolean enter); gboolean _gdk_input_other_event (GdkEvent *event, XEvent *xevent, GdkWindow *window); gint _gdk_input_grab_pointer (GdkWindow *window, + GdkWindow *native_window, gint owner_events, GdkEventMask event_mask, GdkWindow *confine_to, @@ -172,22 +167,21 @@ gint _gdk_input_common_init (GdkDisplay *display, gint include_core); GdkDevicePrivate * _gdk_input_find_device (GdkDisplay *display, guint32 id); -void _gdk_input_get_root_relative_geometry(Display *display, - Window w, +void _gdk_input_get_root_relative_geometry(GdkWindow *window, int *x_ret, - int *y_ret, - int *width_ret, - int *height_ret); -void _gdk_input_common_find_events (GdkWindow *window, - GdkDevicePrivate *gdkdev, + int *y_ret); +void _gdk_input_common_find_events (GdkDevicePrivate *gdkdev, gint mask, XEventClass *classes, int *num_classes); -void _gdk_input_common_select_events (GdkWindow *window, +void _gdk_input_select_events (GdkWindow *impl_window, GdkDevicePrivate *gdkdev); gint _gdk_input_common_other_event (GdkEvent *event, XEvent *xevent, - GdkInputWindow *input_window, + GdkWindow *window, + GdkDevicePrivate *gdkdev); +gboolean _gdk_input_common_event_selected (GdkEvent *event, + GdkWindow *window, GdkDevicePrivate *gdkdev); #endif /* !XINPUT_NONE */ diff --git a/gdk/x11/gdkmain-x11.c b/gdk/x11/gdkmain-x11.c index 7bede228a1..f12c7094b8 100644 --- a/gdk/x11/gdkmain-x11.c +++ b/gdk/x11/gdkmain-x11.c @@ -44,6 +44,7 @@ #include "gdk.h" #include "gdkx.h" +#include "gdkasync.h" #include "gdkdisplay-x11.h" #include "gdkinternals.h" #include "gdkintl.h" @@ -138,56 +139,21 @@ gdk_x11_convert_grab_status (gint status) } static void -generate_grab_broken_event (GdkWindow *window, - gboolean keyboard, - gboolean implicit, - GdkWindow *grab_window) +has_pointer_grab_callback (GdkDisplay *display, + gpointer data, + gulong serial) { - if (!GDK_WINDOW_DESTROYED (window)) - { - GdkEvent event; - - event.type = GDK_GRAB_BROKEN; - event.grab_broken.window = window; - event.grab_broken.send_event = 0; - event.grab_broken.keyboard = keyboard; - event.grab_broken.implicit = implicit; - event.grab_broken.grab_window = grab_window; - - gdk_event_put (&event); - } + _gdk_display_pointer_grab_update (display, serial); } -/* - *-------------------------------------------------------------- - * gdk_pointer_grab - * - * Grabs the pointer to a specific window - * - * Arguments: - * "window" is the window which will receive the grab - * "owner_events" specifies whether events will be reported as is, - * or relative to "window" - * "event_mask" masks only interesting events - * "confine_to" limits the cursor movement to the specified window - * "cursor" changes the cursor for the duration of the grab - * "time" specifies the time - * - * Results: - * - * Side effects: - * requires a corresponding call to gdk_pointer_ungrab - * - *-------------------------------------------------------------- - */ - GdkGrabStatus -gdk_pointer_grab (GdkWindow * window, - gboolean owner_events, - GdkEventMask event_mask, - GdkWindow * confine_to, - GdkCursor * cursor, - guint32 time) +_gdk_windowing_pointer_grab (GdkWindow *window, + GdkWindow *native, + gboolean owner_events, + GdkEventMask event_mask, + GdkWindow *confine_to, + GdkCursor *cursor, + guint32 time) { gint return_val; GdkCursorPrivate *cursor_private; @@ -196,25 +162,22 @@ gdk_pointer_grab (GdkWindow * window, Window xwindow; Window xconfine_to; Cursor xcursor; - unsigned long serial; int i; - - g_return_val_if_fail (window != NULL, 0); - g_return_val_if_fail (GDK_IS_WINDOW (window), 0); - g_return_val_if_fail (confine_to == NULL || GDK_IS_WINDOW (confine_to), 0); - - display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window)); + + if (confine_to) + confine_to = _gdk_window_get_impl_window (confine_to); + + display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (native)); cursor_private = (GdkCursorPrivate*) cursor; - - xwindow = GDK_WINDOW_XID (window); - serial = NextRequest (GDK_WINDOW_XDISPLAY (window)); - + + xwindow = GDK_WINDOW_XID (native); + if (!confine_to || GDK_WINDOW_DESTROYED (confine_to)) xconfine_to = None; else xconfine_to = GDK_WINDOW_XID (confine_to); - + if (!cursor) xcursor = None; else @@ -222,31 +185,37 @@ gdk_pointer_grab (GdkWindow * window, _gdk_x11_cursor_update_theme (cursor); xcursor = cursor_private->xcursor; } - + xevent_mask = 0; for (i = 0; i < _gdk_nenvent_masks; i++) { if (event_mask & (1 << (i + 1))) xevent_mask |= _gdk_event_mask_table[i]; } - + + /* We don't want to set a native motion hint mask, as we're emulating motion + * hints. If we set a native one we just wouldn't get any events. + */ + xevent_mask &= ~PointerMotionHintMask; + return_val = _gdk_input_grab_pointer (window, + native, owner_events, event_mask, confine_to, time); - if (return_val == GrabSuccess || + if (return_val == GrabSuccess || G_UNLIKELY (!display_x11->trusted_client && return_val == AlreadyGrabbed)) { - if (!GDK_WINDOW_DESTROYED (window)) + if (!GDK_WINDOW_DESTROYED (native)) { #ifdef G_ENABLE_DEBUG if (_gdk_debug_flags & GDK_DEBUG_NOGRABS) return_val = GrabSuccess; else #endif - return_val = XGrabPointer (GDK_WINDOW_XDISPLAY (window), + return_val = XGrabPointer (GDK_WINDOW_XDISPLAY (native), xwindow, owner_events, xevent_mask, @@ -258,62 +227,15 @@ gdk_pointer_grab (GdkWindow * window, else return_val = AlreadyGrabbed; } - - if (return_val == GrabSuccess) - { - if (display_x11->pointer_xgrab_window != NULL && - display_x11->pointer_xgrab_window != (GdkWindowObject *)window) - generate_grab_broken_event (GDK_WINDOW (display_x11->pointer_xgrab_window), - FALSE, display_x11->pointer_xgrab_implicit, - window); - display_x11->pointer_xgrab_window = (GdkWindowObject *)window; - display_x11->pointer_xgrab_serial = serial; - display_x11->pointer_xgrab_owner_events = owner_events; - display_x11->pointer_xgrab_time = time; - display_x11->pointer_xgrab_implicit = FALSE; - } + if (return_val == GrabSuccess) + _gdk_x11_roundtrip_async (GDK_DISPLAY_OBJECT (display_x11), + has_pointer_grab_callback, + NULL); return gdk_x11_convert_grab_status (return_val); } -/** - * gdk_pointer_grab_info_libgtk_only: - * @display: the #GdkDisplay for which to get the grab information - * @grab_window: location to store current grab window - * @owner_events: location to store boolean indicating whether - * the @owner_events flag to gdk_pointer_grab() was %TRUE. - * - * Determines information about the current pointer grab. - * This is not public API and must not be used by applications. - * - * Return value: %TRUE if this application currently has the - * pointer grabbed. - **/ -gboolean -gdk_pointer_grab_info_libgtk_only (GdkDisplay *display, - GdkWindow **grab_window, - gboolean *owner_events) -{ - GdkDisplayX11 *display_x11; - - g_return_val_if_fail (GDK_IS_DISPLAY (display), False); - - display_x11 = GDK_DISPLAY_X11 (display); - - if (display_x11->pointer_xgrab_window) - { - if (grab_window) - *grab_window = (GdkWindow *)display_x11->pointer_xgrab_window; - if (owner_events) - *owner_events = display_x11->pointer_xgrab_owner_events; - - return TRUE; - } - else - return FALSE; -} - /* *-------------------------------------------------------------- * gdk_keyboard_grab @@ -341,24 +263,33 @@ gdk_keyboard_grab (GdkWindow * window, { gint return_val; unsigned long serial; + GdkDisplay *display; GdkDisplayX11 *display_x11; - + GdkWindow *native; + g_return_val_if_fail (window != NULL, 0); g_return_val_if_fail (GDK_IS_WINDOW (window), 0); - - display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window)); - serial = NextRequest (GDK_WINDOW_XDISPLAY (window)); + native = gdk_window_get_toplevel (window); - if (!GDK_WINDOW_DESTROYED (window)) + /* TODO: What do we do for offscreens and children? We need to proxy the grab somehow */ + if (!GDK_IS_WINDOW_IMPL_X11 (GDK_WINDOW_OBJECT (native)->impl)) + return GDK_GRAB_SUCCESS; + + display = GDK_WINDOW_DISPLAY (native); + display_x11 = GDK_DISPLAY_X11 (display); + + serial = NextRequest (GDK_WINDOW_XDISPLAY (native)); + + if (!GDK_WINDOW_DESTROYED (native)) { #ifdef G_ENABLE_DEBUG if (_gdk_debug_flags & GDK_DEBUG_NOGRABS) return_val = GrabSuccess; else #endif - return_val = XGrabKeyboard (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XID (window), + return_val = XGrabKeyboard (GDK_WINDOW_XDISPLAY (native), + GDK_WINDOW_XID (native), owner_events, GrabModeAsync, GrabModeAsync, time); @@ -371,58 +302,14 @@ gdk_keyboard_grab (GdkWindow * window, return_val = AlreadyGrabbed; if (return_val == GrabSuccess) - { - if (display_x11->keyboard_xgrab_window != NULL && - display_x11->keyboard_xgrab_window != (GdkWindowObject *)window) - generate_grab_broken_event (GDK_WINDOW (display_x11->keyboard_xgrab_window), - TRUE, FALSE, window); - - display_x11->keyboard_xgrab_window = (GdkWindowObject *)window; - display_x11->keyboard_xgrab_serial = serial; - display_x11->keyboard_xgrab_owner_events = owner_events; - display_x11->keyboard_xgrab_time = time; - } + _gdk_display_set_has_keyboard_grab (display, + window, native, + owner_events, + serial, time); return gdk_x11_convert_grab_status (return_val); } -/** - * gdk_keyboard_grab_info_libgtk_only: - * @display: the display for which to get the grab information - * @grab_window: location to store current grab window - * @owner_events: location to store boolean indicating whether - * the @owner_events flag to gdk_keyboard_grab() was %TRUE. - * - * Determines information about the current keyboard grab. - * This is not public API and must not be used by applications. - * - * Return value: %TRUE if this application currently has the - * keyboard grabbed. - **/ -gboolean -gdk_keyboard_grab_info_libgtk_only (GdkDisplay *display, - GdkWindow **grab_window, - gboolean *owner_events) -{ - GdkDisplayX11 *display_x11; - - g_return_val_if_fail (GDK_IS_DISPLAY (display), False); - - display_x11 = GDK_DISPLAY_X11 (display); - - if (display_x11->keyboard_xgrab_window) - { - if (grab_window) - *grab_window = (GdkWindow *)display_x11->keyboard_xgrab_window; - if (owner_events) - *owner_events = display_x11->keyboard_xgrab_owner_events; - - return TRUE; - } - else - return FALSE; -} - /** * _gdk_xgrab_check_unmap: * @window: a #GdkWindow @@ -437,42 +324,21 @@ void _gdk_xgrab_check_unmap (GdkWindow *window, gulong serial) { - GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (gdk_drawable_get_display (window)); - - if (display_x11->pointer_xgrab_window && - serial >= display_x11->pointer_xgrab_serial) + GdkDisplay *display = gdk_drawable_get_display (window); + + _gdk_display_end_pointer_grab (display, serial, window, TRUE); + + if (display->keyboard_grab.window && + serial >= display->keyboard_grab.serial) { GdkWindowObject *private = GDK_WINDOW_OBJECT (window); - GdkWindowObject *tmp = display_x11->pointer_xgrab_window; + GdkWindowObject *tmp = GDK_WINDOW_OBJECT (display->keyboard_grab.window); while (tmp && tmp != private) tmp = tmp->parent; if (tmp) - { - generate_grab_broken_event (GDK_WINDOW (display_x11->pointer_xgrab_window), - FALSE, display_x11->pointer_xgrab_implicit, - NULL); - display_x11->pointer_xgrab_window = NULL; - } - } - - if (display_x11->keyboard_xgrab_window && - serial >= display_x11->keyboard_xgrab_serial) - { - GdkWindowObject *private = GDK_WINDOW_OBJECT (window); - GdkWindowObject *tmp = display_x11->keyboard_xgrab_window; - - - while (tmp && tmp != private) - tmp = tmp->parent; - - if (tmp) - { - generate_grab_broken_event (GDK_WINDOW (display_x11->keyboard_xgrab_window), - TRUE, FALSE, NULL); - display_x11->keyboard_xgrab_window = NULL; - } + _gdk_display_unset_has_keyboard_grab (display, TRUE); } } @@ -486,67 +352,26 @@ _gdk_xgrab_check_unmap (GdkWindow *window, void _gdk_xgrab_check_destroy (GdkWindow *window) { - GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (gdk_drawable_get_display (window)); + GdkDisplay *display = gdk_drawable_get_display (window); + GdkPointerGrabInfo *grab; + + /* Make sure there is no lasting grab in this native + window */ + grab = _gdk_display_get_last_pointer_grab (display); + if (grab && grab->native_window == window) + { + /* We don't know the actual serial to end, but it + doesn't really matter as this only happens + after we get told of the destroy from the + server so we know its ended in the server, + just make sure its ended. */ + grab->serial_end = grab->serial_start; + grab->implicit_ungrab = TRUE; + } - if ((GdkWindowObject *)window == display_x11->pointer_xgrab_window) - { - generate_grab_broken_event (GDK_WINDOW (display_x11->pointer_xgrab_window), - FALSE, display_x11->pointer_xgrab_implicit, - NULL); - display_x11->pointer_xgrab_window = NULL; - } - - if ((GdkWindowObject *)window == display_x11->keyboard_xgrab_window) - { - generate_grab_broken_event (GDK_WINDOW (display_x11->keyboard_xgrab_window), - TRUE, FALSE, NULL); - display_x11->keyboard_xgrab_window = NULL; - } -} - -#define GDK_ANY_BUTTON_MASK (GDK_BUTTON1_MASK | \ - GDK_BUTTON2_MASK | \ - GDK_BUTTON3_MASK | \ - GDK_BUTTON4_MASK | \ - GDK_BUTTON5_MASK) - -/** - * _gdk_xgrab_check_button_event: - * @window: a #GdkWindow - * @event: an XEvent of type ButtonPress or ButtonRelease - * - * Checks to see if a button event starts or ends an implicit grab. - **/ -void -_gdk_xgrab_check_button_event (GdkWindow *window, - XEvent *xevent) -{ - GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (gdk_drawable_get_display (window)); - - /* track implicit grabs for button presses */ - switch (xevent->type) - { - case ButtonPress: - if (!display_x11->pointer_xgrab_window) - { - display_x11->pointer_xgrab_window = (GdkWindowObject *)window; - display_x11->pointer_xgrab_serial = xevent->xany.serial; - display_x11->pointer_xgrab_owner_events = FALSE; - display_x11->pointer_xgrab_time = xevent->xbutton.time; - display_x11->pointer_xgrab_implicit = TRUE; - } - break; - case ButtonRelease: - if (display_x11->pointer_xgrab_window && - display_x11->pointer_xgrab_implicit && - (xevent->xbutton.state & GDK_ANY_BUTTON_MASK & ~(GDK_BUTTON1_MASK << (xevent->xbutton.button - 1))) == 0) - { - display_x11->pointer_xgrab_window = NULL; - } - break; - default: - g_assert_not_reached (); - } + if (window == display->keyboard_grab.native_window && + display->keyboard_grab.window != NULL) + _gdk_display_unset_has_keyboard_grab (display, TRUE); } void diff --git a/gdk/x11/gdkpixmap-x11.c b/gdk/x11/gdkpixmap-x11.c index 7984b5a089..7e86dbb72f 100644 --- a/gdk/x11/gdkpixmap-x11.c +++ b/gdk/x11/gdkpixmap-x11.c @@ -137,10 +137,10 @@ gdk_pixmap_impl_x11_get_size (GdkDrawable *drawable, } GdkPixmap* -gdk_pixmap_new (GdkDrawable *drawable, - gint width, - gint height, - gint depth) +_gdk_pixmap_new (GdkDrawable *drawable, + gint width, + gint height, + gint depth) { GdkPixmap *pixmap; GdkDrawableImplX11 *draw_impl; @@ -194,10 +194,10 @@ gdk_pixmap_new (GdkDrawable *drawable, } GdkPixmap * -gdk_bitmap_create_from_data (GdkDrawable *drawable, - const gchar *data, - gint width, - gint height) +_gdk_bitmap_create_from_data (GdkDrawable *drawable, + const gchar *data, + gint width, + gint height) { GdkPixmap *pixmap; GdkDrawableImplX11 *draw_impl; @@ -238,13 +238,13 @@ gdk_bitmap_create_from_data (GdkDrawable *drawable, } GdkPixmap* -gdk_pixmap_create_from_data (GdkDrawable *drawable, - const gchar *data, - gint width, - gint height, - gint depth, - const GdkColor *fg, - const GdkColor *bg) +_gdk_pixmap_create_from_data (GdkDrawable *drawable, + const gchar *data, + gint width, + gint height, + gint depth, + const GdkColor *fg, + const GdkColor *bg) { GdkPixmap *pixmap; GdkDrawableImplX11 *draw_impl; @@ -427,7 +427,7 @@ gdk_pixmap_foreign_new (GdkNativeWindow anid) * For example in the X backend, a native pixmap handle is an Xlib * XID. * - * Return value: the #GdkWindow wrapper for the native window, + * Return value: the #GdkPixmap wrapper for the native pixmap, * or %NULL if there is none. **/ GdkPixmap* diff --git a/gdk/x11/gdkprivate-x11.h b/gdk/x11/gdkprivate-x11.h index f24a0df4c1..bfbf3d9bdd 100644 --- a/gdk/x11/gdkprivate-x11.h +++ b/gdk/x11/gdkprivate-x11.h @@ -118,7 +118,6 @@ GdkImage *_gdk_x11_copy_to_image (GdkDrawable *drawable, Pixmap _gdk_x11_image_get_shm_pixmap (GdkImage *image); /* Routines from gdkgeometry-x11.c */ -void _gdk_window_init_position (GdkWindow *window); void _gdk_window_move_resize_child (GdkWindow *window, gint x, gint y, @@ -128,13 +127,13 @@ void _gdk_window_process_expose (GdkWindow *window, gulong serial, GdkRectangle *area); -void _gdk_x11_window_scroll (GdkWindow *window, - gint dx, - gint dy); -void _gdk_x11_window_move_region (GdkWindow *window, - const GdkRegion *region, - gint dx, - gint dy); +gboolean _gdk_x11_window_queue_antiexpose (GdkWindow *window, + GdkRegion *area); +void _gdk_x11_window_queue_translation (GdkWindow *window, + GdkGC *gc, + GdkRegion *area, + gint dx, + gint dy); void _gdk_selection_window_destroyed (GdkWindow *window); gboolean _gdk_selection_filter_clear_event (XSelectionClearEvent *event); @@ -166,8 +165,6 @@ void _gdk_x11_initialize_locale (void); void _gdk_xgrab_check_unmap (GdkWindow *window, gulong serial); void _gdk_xgrab_check_destroy (GdkWindow *window); -void _gdk_xgrab_check_button_event (GdkWindow *window, - XEvent *xevent); gboolean _gdk_x11_display_is_root_window (GdkDisplay *display, Window xroot_window); @@ -216,5 +213,6 @@ extern gboolean _gdk_synchronize; #define GDK_WINDOW_DISPLAY(win) (GDK_SCREEN_X11 (GDK_WINDOW_SCREEN (win))->display) #define GDK_WINDOW_XROOTWIN(win) (GDK_SCREEN_X11 (GDK_WINDOW_SCREEN (win))->xroot_window) #define GDK_GC_DISPLAY(gc) (GDK_SCREEN_DISPLAY (GDK_GC_X11(gc)->screen)) +#define GDK_WINDOW_IS_X11(win) (GDK_IS_WINDOW_IMPL_X11 (((GdkWindowObject *)win)->impl)) #endif /* __GDK_PRIVATE_X11_H__ */ diff --git a/gdk/x11/gdkproperty-x11.c b/gdk/x11/gdkproperty-x11.c index c415dee383..b0ce21b35f 100644 --- a/gdk/x11/gdkproperty-x11.c +++ b/gdk/x11/gdkproperty-x11.c @@ -296,7 +296,9 @@ gdk_x11_xatom_to_atom_for_display (GdkDisplay *display, GdkAtom virtual_atom = GDK_NONE; g_return_val_if_fail (GDK_IS_DISPLAY (display), GDK_NONE); - g_return_val_if_fail (xatom != None, GDK_NONE); + + if (xatom == None) + return GDK_NONE; if (display->closed) return GDK_NONE; @@ -546,7 +548,7 @@ gdk_property_get (GdkWindow *window, Atom xtype; int res; - g_return_val_if_fail (!window || GDK_IS_WINDOW (window), FALSE); + g_return_val_if_fail (!window || GDK_WINDOW_IS_X11 (window), FALSE); if (!window) { @@ -555,6 +557,8 @@ gdk_property_get (GdkWindow *window, GDK_NOTE (MULTIHEAD, g_message ("gdk_property_get(): window is NULL\n")); } + else if (!GDK_WINDOW_IS_X11 (window)) + return FALSE; if (GDK_WINDOW_DESTROYED (window)) return FALSE; @@ -680,7 +684,7 @@ gdk_property_change (GdkWindow *window, Atom xproperty; Atom xtype; - g_return_if_fail (!window || GDK_IS_WINDOW (window)); + g_return_if_fail (!window || GDK_WINDOW_IS_X11 (window)); if (!window) { @@ -691,7 +695,8 @@ gdk_property_change (GdkWindow *window, GDK_NOTE (MULTIHEAD, g_message ("gdk_property_change(): window is NULL\n")); } - + else if (!GDK_WINDOW_IS_X11 (window)) + return; if (GDK_WINDOW_DESTROYED (window)) return; @@ -731,7 +736,7 @@ void gdk_property_delete (GdkWindow *window, GdkAtom property) { - g_return_if_fail (!window || GDK_IS_WINDOW (window)); + g_return_if_fail (!window || GDK_WINDOW_IS_X11 (window)); if (!window) { @@ -741,6 +746,8 @@ gdk_property_delete (GdkWindow *window, GDK_NOTE (MULTIHEAD, g_message ("gdk_property_delete(): window is NULL\n")); } + else if (!GDK_WINDOW_IS_X11 (window)) + return; if (GDK_WINDOW_DESTROYED (window)) return; diff --git a/gdk/x11/gdkscreen-x11.c b/gdk/x11/gdkscreen-x11.c index cbf0930005..1faa827ae2 100644 --- a/gdk/x11/gdkscreen-x11.c +++ b/gdk/x11/gdkscreen-x11.c @@ -377,7 +377,7 @@ get_monitor (GdkScreen *screen, * * Gets the width in millimeters of the specified monitor, if available. * - * Returns the width of the monitor, or -1 if not available + * Returns: the width of the monitor, or -1 if not available * * Since: 2.14 */ @@ -989,8 +989,6 @@ _gdk_x11_screen_new (GdkDisplay *display, screen_x11->wmspec_check_window = None; /* we want this to be always non-null */ screen_x11->window_manager_name = g_strdup ("unknown"); - screen_x11->cm_selection_atom = make_cm_atom (screen_number); - screen_x11->is_composited = check_is_composited (display, screen_x11); init_multihead (screen); init_randr_support (screen); @@ -1001,6 +999,22 @@ _gdk_x11_screen_new (GdkDisplay *display, return screen; } +/* + * It is important that we first request the selection + * notification, and then setup the initial state of + * is_composited to avoid a race condition here. + */ +void +_gdk_x11_screen_setup (GdkScreen *screen) +{ + GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen); + + screen_x11->cm_selection_atom = make_cm_atom (screen_x11->screen_num); + gdk_display_request_selection_notification (screen_x11->display, + screen_x11->cm_selection_atom); + screen_x11->is_composited = check_is_composited (screen_x11->display, screen_x11); +} + /** * gdk_screen_is_composited: * @screen: a #GdkScreen @@ -1078,7 +1092,6 @@ _gdk_x11_screen_size_changed (GdkScreen *screen, { gint width, height; GdkDisplayX11 *display_x11; - gboolean monitors_changed; width = gdk_screen_get_width (screen); height = gdk_screen_get_height (screen); diff --git a/gdk/x11/gdkscreen-x11.h b/gdk/x11/gdkscreen-x11.h index 8a743f5d84..0d1548cdbb 100644 --- a/gdk/x11/gdkscreen-x11.h +++ b/gdk/x11/gdkscreen-x11.h @@ -122,6 +122,7 @@ GType _gdk_screen_x11_get_type (void); GdkScreen * _gdk_x11_screen_new (GdkDisplay *display, gint screen_number); +void _gdk_x11_screen_setup (GdkScreen *screen); void _gdk_x11_screen_window_manager_changed (GdkScreen *screen); void _gdk_x11_screen_size_changed (GdkScreen *screen, XEvent *event); diff --git a/gdk/x11/gdkselection-x11.c b/gdk/x11/gdkselection-x11.c index 6045dadea3..f993b5bf45 100644 --- a/gdk/x11/gdkselection-x11.c +++ b/gdk/x11/gdkselection-x11.c @@ -141,9 +141,10 @@ gdk_selection_owner_set_for_display (GdkDisplay *display, if (owner) { - if (GDK_WINDOW_DESTROYED (owner)) + if (GDK_WINDOW_DESTROYED (owner) || !GDK_WINDOW_IS_X11 (owner)) return FALSE; + gdk_window_ensure_native (owner); xdisplay = GDK_WINDOW_XDISPLAY (owner); xwindow = GDK_WINDOW_XID (owner); } @@ -230,10 +231,11 @@ gdk_selection_convert (GdkWindow *requestor, GdkDisplay *display; g_return_if_fail (selection != GDK_NONE); - - if (GDK_WINDOW_DESTROYED (requestor)) + + if (GDK_WINDOW_DESTROYED (requestor) || !GDK_WINDOW_IS_X11 (requestor)) return; + gdk_window_ensure_native (requestor); display = GDK_WINDOW_DISPLAY (requestor); XConvertSelection (GDK_WINDOW_XDISPLAY (requestor), @@ -279,10 +281,11 @@ gdk_selection_property_get (GdkWindow *requestor, g_return_val_if_fail (requestor != NULL, 0); g_return_val_if_fail (GDK_IS_WINDOW (requestor), 0); + g_return_val_if_fail (GDK_WINDOW_IS_X11 (requestor), 0); display = GDK_WINDOW_DISPLAY (requestor); - if (GDK_WINDOW_DESTROYED (requestor)) + if (GDK_WINDOW_DESTROYED (requestor) || !GDK_WINDOW_IS_X11 (requestor)) goto err; t = NULL; diff --git a/gdk/x11/gdktestutils-x11.c b/gdk/x11/gdktestutils-x11.c index 480da4d909..13677b6a42 100644 --- a/gdk/x11/gdktestutils-x11.c +++ b/gdk/x11/gdktestutils-x11.c @@ -86,6 +86,7 @@ gdk_test_simulate_key (GdkWindow *window, { GdkScreen *screen; GdkKeymapKey *keys = NULL; + GdkWindowObject *priv; gboolean success; gint n_keys = 0; XKeyEvent xev = { @@ -104,6 +105,12 @@ gdk_test_simulate_key (GdkWindow *window, x /= 2; y /= 2; } + + priv = (GdkWindowObject *)window; + /* Convert to impl coordinates */ + x = x + priv->abs_x; + y = y + priv->abs_y; + xev.type = key_pressrelease == GDK_KEY_PRESS ? KeyPress : KeyRelease; xev.display = GDK_DRAWABLE_XDISPLAY (window); xev.window = GDK_WINDOW_XID (window); @@ -190,6 +197,7 @@ gdk_test_simulate_button (GdkWindow *window, 1, /* send_event */ }; gboolean success; + GdkWindowObject *priv; g_return_val_if_fail (button_pressrelease == GDK_BUTTON_PRESS || button_pressrelease == GDK_BUTTON_RELEASE, FALSE); g_return_val_if_fail (window != NULL, FALSE); @@ -203,6 +211,12 @@ gdk_test_simulate_button (GdkWindow *window, x /= 2; y /= 2; } + + priv = (GdkWindowObject *)window; + /* Convert to impl coordinates */ + x = x + priv->abs_x; + y = y + priv->abs_y; + xev.type = button_pressrelease == GDK_BUTTON_PRESS ? ButtonPress : ButtonRelease; xev.display = GDK_DRAWABLE_XDISPLAY (window); xev.window = GDK_WINDOW_XID (window); diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c index bfaa7a1178..c65a0d4f26 100644 --- a/gdk/x11/gdkwindow-x11.c +++ b/gdk/x11/gdkwindow-x11.c @@ -110,16 +110,17 @@ static void move_to_current_desktop (GdkWindow *window); static GdkColormap* gdk_window_impl_x11_get_colormap (GdkDrawable *drawable); static void gdk_window_impl_x11_set_colormap (GdkDrawable *drawable, GdkColormap *cmap); -static void gdk_window_impl_x11_get_size (GdkDrawable *drawable, - gint *width, - gint *height); -static GdkRegion* gdk_window_impl_x11_get_visible_region (GdkDrawable *drawable); static void gdk_window_impl_x11_finalize (GObject *object); static void gdk_window_impl_iface_init (GdkWindowImplIface *iface); -#define WINDOW_IS_TOPLEVEL(window) \ - (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \ - GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN) +#define WINDOW_IS_TOPLEVEL_OR_FOREIGN(window) \ + (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \ + GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN) + +#define WINDOW_IS_TOPLEVEL(window) \ + (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \ + GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN && \ + GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN) /* Return whether time1 is considered later than time2 as far as xserver * time is concerned. Accounts for wraparound. @@ -144,8 +145,6 @@ _gdk_window_impl_get_type (void) static void gdk_window_impl_x11_init (GdkWindowImplX11 *impl) { - impl->width = 1; - impl->height = 1; impl->toplevel_window_type = -1; } @@ -179,11 +178,6 @@ gdk_window_impl_x11_class_init (GdkWindowImplX11Class *klass) drawable_class->set_colormap = gdk_window_impl_x11_set_colormap; drawable_class->get_colormap = gdk_window_impl_x11_get_colormap; - drawable_class->get_size = gdk_window_impl_x11_get_size; - - /* Visible and clip regions are the same */ - drawable_class->get_clip_region = gdk_window_impl_x11_get_visible_region; - drawable_class->get_visible_region = gdk_window_impl_x11_get_visible_region; } static void @@ -228,14 +222,7 @@ tmp_unset_bg (GdkWindow *window) obj = (GdkWindowObject *) window; impl = GDK_WINDOW_IMPL_X11 (obj->impl); - /* For windows without EXPOSURE_MASK, we can't do this - * unsetting because such windows depend on the drawing - * that the X server is going to do - */ - if (!(obj->event_mask & GDK_EXPOSURE_MASK)) - return; - - impl->position_info.no_bg = TRUE; + impl->no_bg = TRUE; if (obj->bg_pixmap != GDK_NO_BG) XSetWindowBackgroundPixmap (GDK_DRAWABLE_XDISPLAY (window), @@ -251,10 +238,7 @@ tmp_reset_bg (GdkWindow *window) obj = (GdkWindowObject *) window; impl = GDK_WINDOW_IMPL_X11 (obj->impl); - if (!(obj->event_mask & GDK_EXPOSURE_MASK)) - return; - - impl->position_info.no_bg = FALSE; + impl->no_bg = FALSE; if (obj->bg_pixmap == GDK_NO_BG) return; @@ -299,15 +283,13 @@ _gdk_x11_window_tmp_unset_bg (GdkWindow *window, if (private->input_only || private->destroyed || (private->window_type != GDK_WINDOW_ROOT && !GDK_WINDOW_IS_MAPPED (window))) - { - return; - } - - if (private->window_type != GDK_WINDOW_ROOT && + return; + + if (_gdk_window_has_impl (window) && + GDK_WINDOW_IS_X11 (window) && + private->window_type != GDK_WINDOW_ROOT && private->window_type != GDK_WINDOW_FOREIGN) - { - tmp_unset_bg (window); - } + tmp_unset_bg (window); if (recurse) { @@ -318,6 +300,19 @@ _gdk_x11_window_tmp_unset_bg (GdkWindow *window, } } +void +_gdk_x11_window_tmp_unset_parent_bg (GdkWindow *window) +{ + GdkWindowObject *private; + private = (GdkWindowObject*) window; + + if (GDK_WINDOW_TYPE (private->parent) == GDK_WINDOW_ROOT) + return; + + window = _gdk_window_get_impl_window ((GdkWindow *)private->parent); + _gdk_x11_window_tmp_unset_bg (window, FALSE); +} + void _gdk_x11_window_tmp_reset_bg (GdkWindow *window, gboolean recurse) @@ -331,15 +326,14 @@ _gdk_x11_window_tmp_reset_bg (GdkWindow *window, if (private->input_only || private->destroyed || (private->window_type != GDK_WINDOW_ROOT && !GDK_WINDOW_IS_MAPPED (window))) - { - return; - } + return; - if (private->window_type != GDK_WINDOW_ROOT && + + if (_gdk_window_has_impl (window) && + GDK_WINDOW_IS_X11 (window) && + private->window_type != GDK_WINDOW_ROOT && private->window_type != GDK_WINDOW_FOREIGN) - { - tmp_reset_bg (window); - } + tmp_reset_bg (window); if (recurse) { @@ -350,6 +344,20 @@ _gdk_x11_window_tmp_reset_bg (GdkWindow *window, } } +void +_gdk_x11_window_tmp_reset_parent_bg (GdkWindow *window) +{ + GdkWindowObject *private; + private = (GdkWindowObject*) window; + + if (GDK_WINDOW_TYPE (private->parent) == GDK_WINDOW_ROOT) + return; + + window = _gdk_window_get_impl_window ((GdkWindow *)private->parent); + + _gdk_x11_window_tmp_reset_bg (window, FALSE); +} + static GdkColormap* gdk_window_impl_x11_get_colormap (GdkDrawable *drawable) { @@ -407,40 +415,10 @@ gdk_window_impl_x11_set_colormap (GdkDrawable *drawable, } -static void -gdk_window_impl_x11_get_size (GdkDrawable *drawable, - gint *width, - gint *height) -{ - g_return_if_fail (GDK_IS_WINDOW_IMPL_X11 (drawable)); - - if (width) - *width = GDK_WINDOW_IMPL_X11 (drawable)->width; - if (height) - *height = GDK_WINDOW_IMPL_X11 (drawable)->height; -} - -static GdkRegion* -gdk_window_impl_x11_get_visible_region (GdkDrawable *drawable) -{ - GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (drawable); - GdkRectangle result_rect; - - result_rect.x = 0; - result_rect.y = 0; - result_rect.width = impl->width; - result_rect.height = impl->height; - - gdk_rectangle_intersect (&result_rect, &impl->position_info.clip_rect, &result_rect); - - return gdk_region_rectangle (&result_rect); -} - void _gdk_windowing_window_init (GdkScreen * screen) { GdkWindowObject *private; - GdkWindowImplX11 *impl; GdkDrawableImplX11 *draw_impl; GdkScreenX11 *screen_x11; @@ -455,8 +433,8 @@ _gdk_windowing_window_init (GdkScreen * screen) private = (GdkWindowObject *) screen_x11->root_window; private->impl = g_object_new (_gdk_window_impl_get_type (), NULL); + private->impl_window = private; - impl = GDK_WINDOW_IMPL_X11 (private->impl); draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl); draw_impl->screen = screen; @@ -467,12 +445,20 @@ _gdk_windowing_window_init (GdkScreen * screen) private->window_type = GDK_WINDOW_ROOT; private->depth = DefaultDepthOfScreen (screen_x11->xscreen); - - impl->width = WidthOfScreen (screen_x11->xscreen); - impl->height = HeightOfScreen (screen_x11->xscreen); - - _gdk_window_init_position (GDK_WINDOW (private)); + private->x = 0; + private->y = 0; + private->abs_x = 0; + private->abs_y = 0; + private->width = WidthOfScreen (screen_x11->xscreen); + private->height = HeightOfScreen (screen_x11->xscreen); + private->viewable = TRUE; + + /* see init_randr_support() in gdkscreen-x11.c */ + private->event_mask = GDK_STRUCTURE_MASK; + + _gdk_window_update_size (screen_x11->root_window); + _gdk_xid_table_insert (screen_x11->display, &screen_x11->xroot_window, screen_x11->root_window); @@ -587,7 +573,6 @@ setup_toplevel_window (GdkWindow *window, { GdkWindowObject *obj = (GdkWindowObject *)window; GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window); - GdkWindowImplX11 *impl = (GdkWindowImplX11 *)obj->impl; Display *xdisplay = GDK_WINDOW_XDISPLAY (window); XID xid = GDK_WINDOW_XID (window); XID xparent = GDK_WINDOW_XID (parent); @@ -617,8 +602,8 @@ setup_toplevel_window (GdkWindow *window, * correct value??? */ size_hints.flags = PSize; - size_hints.width = impl->width; - size_hints.height = impl->height; + size_hints.width = obj->width; + size_hints.height = obj->height; XSetWMNormalHints (xdisplay, xid, &size_hints); @@ -654,19 +639,20 @@ setup_toplevel_window (GdkWindow *window, ensure_sync_counter (window); } -GdkWindow * -_gdk_window_new (GdkWindow *parent, - GdkWindowAttr *attributes, - gint attributes_mask) +void +_gdk_window_impl_new (GdkWindow *window, + GdkWindow *real_parent, + GdkScreen *screen, + GdkVisual *visual, + GdkEventMask event_mask, + GdkWindowAttr *attributes, + gint attributes_mask) { - GdkWindow *window; GdkWindowObject *private; GdkWindowImplX11 *impl; GdkDrawableImplX11 *draw_impl; GdkScreenX11 *screen_x11; - GdkScreen *screen; - GdkVisual *visual; Window xparent; Visual *xvisual; Display *xdisplay; @@ -675,117 +661,34 @@ _gdk_window_new (GdkWindow *parent, XSetWindowAttributes xattributes; long xattributes_mask; XClassHint *class_hint; - int x, y, depth; unsigned int class; const char *title; int i; - g_return_val_if_fail (attributes != NULL, NULL); - - if (!parent) - { - GDK_NOTE (MULTIHEAD, - g_warning ("gdk_window_new(): no parent specified reverting to parent = default root window")); - - screen = gdk_screen_get_default (); - parent = gdk_screen_get_root_window (screen); - } - else - screen = gdk_drawable_get_screen (parent); - - screen_x11 = GDK_SCREEN_X11 (screen); - - g_return_val_if_fail (GDK_IS_WINDOW (parent), NULL); - - if (GDK_WINDOW_DESTROYED (parent)) - return NULL; - - xparent = GDK_WINDOW_XID (parent); - - window = g_object_new (GDK_TYPE_WINDOW, NULL); - private = (GdkWindowObject *) window; - private->impl = g_object_new (_gdk_window_impl_get_type (), NULL); - - impl = GDK_WINDOW_IMPL_X11 (private->impl); - draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl); + + screen_x11 = GDK_SCREEN_X11 (screen); + xparent = GDK_WINDOW_XID (real_parent); + + impl = g_object_new (_gdk_window_impl_get_type (), NULL); + private->impl = (GdkDrawable *)impl; + draw_impl = GDK_DRAWABLE_IMPL_X11 (impl); draw_impl->wrapper = GDK_DRAWABLE (window); draw_impl->screen = screen; xdisplay = screen_x11->xdisplay; - /* Windows with a foreign parent are treated as if they are children - * of the root window, except for actual creation. - */ - if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_FOREIGN) - parent = gdk_screen_get_root_window (screen); - - private->parent = (GdkWindowObject *)parent; - - private->accept_focus = TRUE; - private->focus_on_map = TRUE; - xattributes_mask = 0; - - if (attributes_mask & GDK_WA_X) - x = attributes->x; - else - x = 0; - - if (attributes_mask & GDK_WA_Y) - y = attributes->y; - else - y = 0; - - private->x = x; - private->y = y; - impl->width = (attributes->width > 1) ? (attributes->width) : (1); - impl->height = (attributes->height > 1) ? (attributes->height) : (1); - if (attributes->wclass == GDK_INPUT_ONLY) - { - /* Backwards compatiblity - we've always ignored - * attributes->window_type for input-only windows - * before - */ - if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_ROOT) - private->window_type = GDK_WINDOW_TEMP; - else - private->window_type = GDK_WINDOW_CHILD; - } - else - private->window_type = attributes->window_type; - - /* Work around a bug where Xorg refuses to map toplevel InputOnly windows - * from an untrusted client: http://bugs.freedesktop.org/show_bug.cgi?id=6988 - */ - if (attributes->wclass == GDK_INPUT_ONLY && - GDK_WINDOW_TYPE (parent) == GDK_WINDOW_ROOT && - !G_LIKELY (GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (parent))->trusted_client)) - { - g_warning ("Coercing GDK_INPUT_ONLY toplevel window to GDK_INPUT_OUTPUT to work around bug in Xorg server"); - attributes->wclass = GDK_INPUT_OUTPUT; - } - - _gdk_window_init_position (GDK_WINDOW (private)); - if (impl->position_info.big) - private->guffaw_gravity = TRUE; - - if (attributes_mask & GDK_WA_VISUAL) - visual = attributes->visual; - else - visual = gdk_screen_get_system_visual (screen); xvisual = ((GdkVisualPrivate*) visual)->xvisual; xattributes.event_mask = StructureNotifyMask | PropertyChangeMask; for (i = 0; i < _gdk_nenvent_masks; i++) { - if (attributes->event_mask & (1 << (i + 1))) + if (event_mask & (1 << (i + 1))) xattributes.event_mask |= _gdk_event_mask_table[i]; } - private->event_mask = attributes->event_mask; - if (xattributes.event_mask) xattributes_mask |= CWEventMask; @@ -812,27 +715,17 @@ _gdk_window_new (GdkWindow *parent, case GDK_WINDOW_TOPLEVEL: case GDK_WINDOW_DIALOG: case GDK_WINDOW_TEMP: - if (GDK_WINDOW_TYPE (parent) != GDK_WINDOW_ROOT) + if (GDK_WINDOW_TYPE (private->parent) != GDK_WINDOW_ROOT) { - g_warning (G_STRLOC "Toplevel windows must be created as children of\n" - "of a window of type GDK_WINDOW_ROOT or GDK_WINDOW_FOREIGN"); + /* The common code warns for this case */ xparent = GDK_SCREEN_XROOTWIN (screen); } - case GDK_WINDOW_CHILD: - break; - default: - g_warning (G_STRLOC "cannot make windows of type %d", private->window_type); - return NULL; } - if (attributes->wclass == GDK_INPUT_OUTPUT) + if (!private->input_only) { class = InputOutput; - depth = visual->depth; - private->input_only = FALSE; - private->depth = depth; - if (attributes_mask & GDK_WA_COLORMAP) { draw_impl->colormap = attributes->colormap; @@ -851,12 +744,8 @@ _gdk_window_new (GdkWindow *parent, } } - private->bg_color.pixel = BlackPixel (xdisplay, screen_x11->screen_num); - private->bg_color.red = private->bg_color.green = private->bg_color.blue = 0; xattributes.background_pixel = private->bg_color.pixel; - private->bg_pixmap = NULL; - xattributes.border_pixel = BlackPixel (xdisplay, screen_x11->screen_num); xattributes_mask |= CWBorderPixel | CWBackPixel; @@ -882,30 +771,32 @@ _gdk_window_new (GdkWindow *parent, } else { - depth = 0; - private->depth = 0; class = InputOnly; - private->input_only = TRUE; draw_impl->colormap = gdk_screen_get_system_colormap (screen); g_object_ref (draw_impl->colormap); } + if (private->width > 65535 || + private->height > 65535) + { + g_warning ("Native Windows wider or taller than 65535 pixels are not supported"); + + if (private->width > 65535) + private->width = 65535; + if (private->height > 65535) + private->height = 65535; + } + xid = draw_impl->xid = XCreateWindow (xdisplay, xparent, - impl->position_info.x, impl->position_info.y, - impl->position_info.width, impl->position_info.height, - 0, depth, class, xvisual, + private->x + private->parent->abs_x, + private->y + private->parent->abs_y, + private->width, private->height, + 0, private->depth, class, xvisual, xattributes_mask, &xattributes); g_object_ref (window); _gdk_xid_table_insert (screen_x11->display, &draw_impl->xid, window); - - gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ? - (attributes->cursor) : - NULL)); - - if (private->parent) - private->parent->children = g_list_prepend (private->parent->children, window); - + switch (GDK_WINDOW_TYPE (private)) { case GDK_WINDOW_DIALOG: @@ -927,11 +818,11 @@ _gdk_window_new (GdkWindow *parent, XFree (class_hint); } - setup_toplevel_window (window, parent); + setup_toplevel_window (window, (GdkWindow *)private->parent); break; case GDK_WINDOW_CHILD: - if ((attributes->wclass == GDK_INPUT_OUTPUT) && + if (!private->input_only && (draw_impl->colormap != gdk_screen_get_system_colormap (screen)) && (draw_impl->colormap != gdk_drawable_get_colormap (gdk_window_get_toplevel (window)))) { @@ -946,8 +837,6 @@ _gdk_window_new (GdkWindow *parent, if (attributes_mask & GDK_WA_TYPE_HINT) gdk_window_set_type_hint (window, attributes->type_hint); - - return window; } static GdkEventMask @@ -1025,6 +914,7 @@ gdk_window_foreign_new_for_display (GdkDisplay *display, private = (GdkWindowObject *) window; private->impl = g_object_new (_gdk_window_impl_get_type (), NULL); + private->impl_window = private; impl = GDK_WINDOW_IMPL_X11 (private->impl); draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl); @@ -1042,8 +932,8 @@ gdk_window_foreign_new_for_display (GdkDisplay *display, private->x = attrs.x; private->y = attrs.y; - impl->width = attrs.width; - impl->height = attrs.height; + private->width = attrs.width; + private->height = attrs.height; private->window_type = GDK_WINDOW_FOREIGN; private->destroyed = FALSE; @@ -1053,13 +943,16 @@ gdk_window_foreign_new_for_display (GdkDisplay *display, private->state = GDK_WINDOW_STATE_WITHDRAWN; else private->state = 0; + private->viewable = TRUE; private->depth = attrs.depth; - _gdk_window_init_position (GDK_WINDOW (private)); - g_object_ref (window); _gdk_xid_table_insert (display, &GDK_WINDOW_XID (window), window); + + /* Update the clip region, etc */ + _gdk_window_update_size (window); + return window; } @@ -1138,10 +1031,10 @@ gdk_toplevel_x11_free_contents (GdkDisplay *display, #endif } -void -_gdk_windowing_window_destroy (GdkWindow *window, - gboolean recursing, - gboolean foreign_destroy) +static void +_gdk_x11_window_destroy (GdkWindow *window, + gboolean recursing, + gboolean foreign_destroy) { GdkWindowObject *private = (GdkWindowObject *)window; GdkToplevelX11 *toplevel; @@ -1150,9 +1043,6 @@ _gdk_windowing_window_destroy (GdkWindow *window, _gdk_selection_window_destroyed (window); - if (private->extension_events != 0) - _gdk_input_window_destroy (window); - toplevel = _gdk_x11_window_get_toplevel (window); if (toplevel) gdk_toplevel_x11_free_contents (GDK_WINDOW_DISPLAY (window), toplevel); @@ -1213,8 +1103,6 @@ gdk_window_destroy_notify (GdkWindow *window) { GdkWindowImplX11 *window_impl; - g_return_if_fail (GDK_IS_WINDOW (window)); - window_impl = GDK_WINDOW_IMPL_X11 (((GdkWindowObject *)window)->impl); if (!GDK_WINDOW_DESTROYED (window)) @@ -1417,66 +1305,44 @@ set_initial_hints (GdkWindow *window) } static void -gdk_window_x11_show (GdkWindow *window, - gboolean raise) +gdk_window_x11_show (GdkWindow *window, gboolean already_mapped) { - GdkWindowObject *private; + GdkWindowObject *private = (GdkWindowObject*) window; GdkDisplay *display; GdkDisplayX11 *display_x11; GdkToplevelX11 *toplevel; - - private = (GdkWindowObject*) window; - if (!private->destroyed) + GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl); + Display *xdisplay = GDK_WINDOW_XDISPLAY (window); + Window xwindow = GDK_WINDOW_XID (window); + gboolean unset_bg; + + if (!already_mapped) + set_initial_hints (window); + + if (WINDOW_IS_TOPLEVEL (window)) { - GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl); - Display *xdisplay = GDK_WINDOW_XDISPLAY (window); - Window xwindow = GDK_WINDOW_XID (window); + display = gdk_drawable_get_display (window); + display_x11 = GDK_DISPLAY_X11 (display); + toplevel = _gdk_x11_window_get_toplevel (window); - if (raise) - XRaiseWindow (xdisplay, xwindow); - - if (!GDK_WINDOW_IS_MAPPED (window)) - { - set_initial_hints (window); - - gdk_synthesize_window_state (window, - GDK_WINDOW_STATE_WITHDRAWN, - 0); - } - - g_assert (GDK_WINDOW_IS_MAPPED (window)); - - if (WINDOW_IS_TOPLEVEL (window)) - { - display = gdk_drawable_get_display (window); - display_x11 = GDK_DISPLAY_X11 (display); - toplevel = _gdk_x11_window_get_toplevel (window); - - if (toplevel->user_time != 0 && + if (toplevel->user_time != 0 && display_x11->user_time != 0 && - XSERVER_TIME_IS_LATER (display_x11->user_time, toplevel->user_time)) - gdk_x11_window_set_user_time (window, display_x11->user_time); - } - - if (impl->position_info.mapped) - { - gboolean unset_bg = !private->input_only && - (private->window_type == GDK_WINDOW_CHILD || - impl->override_redirect) && - gdk_window_is_viewable (window); - - if (unset_bg) - _gdk_x11_window_tmp_unset_bg (window, TRUE); - - XMapWindow (xdisplay, xwindow); - - if (unset_bg) - { - _gdk_x11_window_tmp_reset_bg (window, TRUE); - gdk_window_invalidate_rect (window, NULL, TRUE); - } - } + XSERVER_TIME_IS_LATER (display_x11->user_time, toplevel->user_time)) + gdk_x11_window_set_user_time (window, display_x11->user_time); } + + unset_bg = !private->input_only && + (private->window_type == GDK_WINDOW_CHILD || + impl->override_redirect) && + gdk_window_is_viewable (window); + + if (unset_bg) + _gdk_x11_window_tmp_unset_bg (window, TRUE); + + XMapWindow (xdisplay, xwindow); + + if (unset_bg) + _gdk_x11_window_tmp_reset_bg (window, TRUE); } static void @@ -1489,7 +1355,7 @@ pre_unmap (GdkWindow *window) return; if (private->window_type == GDK_WINDOW_CHILD) - start_window = (GdkWindow *)private->parent; + start_window = _gdk_window_get_impl_window ((GdkWindow *)private->parent); else if (private->window_type == GDK_WINDOW_TEMP) start_window = get_root (window); @@ -1507,7 +1373,7 @@ post_unmap (GdkWindow *window) return; if (private->window_type == GDK_WINDOW_CHILD) - start_window = (GdkWindow *)private->parent; + start_window = _gdk_window_get_impl_window ((GdkWindow *)private->parent); else if (private->window_type == GDK_WINDOW_TEMP) start_window = get_root (window); @@ -1557,24 +1423,12 @@ gdk_window_x11_hide (GdkWindow *window) break; } - if (!private->destroyed) - { - if (GDK_WINDOW_IS_MAPPED (window)) - gdk_synthesize_window_state (window, - 0, - GDK_WINDOW_STATE_WITHDRAWN); - - g_assert (!GDK_WINDOW_IS_MAPPED (window)); - - _gdk_window_clear_update_area (window); - - pre_unmap (window); - - XUnmapWindow (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XID (window)); - - post_unmap (window); - } + _gdk_window_clear_update_area (window); + + pre_unmap (window); + XUnmapWindow (GDK_WINDOW_XDISPLAY (window), + GDK_WINDOW_XID (window)); + post_unmap (window); } static void @@ -1613,7 +1467,7 @@ window_x11_move (GdkWindow *window, { _gdk_window_move_resize_child (window, x, y, - impl->width, impl->height); + private->width, private->height); } else { @@ -1647,7 +1501,6 @@ window_x11_resize (GdkWindow *window, _gdk_window_move_resize_child (window, private->x, private->y, width, height); - _gdk_x11_drawable_update_size (private->impl); } else { @@ -1659,13 +1512,13 @@ window_x11_resize (GdkWindow *window, if (impl->override_redirect) { - impl->width = width; - impl->height = height; + private->width = width; + private->height = height; _gdk_x11_drawable_update_size (private->impl); } else { - if (width != impl->width || height != impl->height) + if (width != private->width || height != private->height) private->resize_count += 1; } } @@ -1706,14 +1559,14 @@ window_x11_move_resize (GdkWindow *window, private->x = x; private->y = y; - impl->width = width; - impl->height = height; + private->width = width; + private->height = height; _gdk_x11_drawable_update_size (private->impl); } else { - if (width != impl->width || height != impl->height) + if (width != private->width || height != private->height) private->resize_count += 1; } } @@ -1746,33 +1599,25 @@ gdk_window_x11_reparent (GdkWindow *window, { GdkWindowObject *window_private; GdkWindowObject *parent_private; - GdkWindowObject *old_parent_private; GdkWindowImplX11 *impl; - gboolean was_toplevel; - - if (!new_parent) - new_parent = gdk_screen_get_root_window (GDK_WINDOW_SCREEN (window)); window_private = (GdkWindowObject*) window; - old_parent_private = (GdkWindowObject*)window_private->parent; parent_private = (GdkWindowObject*) new_parent; impl = GDK_WINDOW_IMPL_X11 (window_private->impl); + _gdk_x11_window_tmp_unset_bg (window, TRUE); + _gdk_x11_window_tmp_unset_parent_bg (window); XReparentWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), GDK_WINDOW_XID (new_parent), - x, y); + parent_private->abs_x + x, parent_private->abs_y + y); + _gdk_x11_window_tmp_reset_parent_bg (window); + _gdk_x11_window_tmp_reset_bg (window, TRUE); - window_private->x = x; - window_private->y = y; - - /* From here on, we treat parents of type GDK_WINDOW_FOREIGN like - * the root window - */ if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN) new_parent = gdk_screen_get_root_window (GDK_WINDOW_SCREEN (window)); - window_private->parent = (GdkWindowObject *)new_parent; + window_private->parent = parent_private; /* Switch the window type as appropriate */ @@ -1780,83 +1625,115 @@ gdk_window_x11_reparent (GdkWindow *window, { case GDK_WINDOW_ROOT: case GDK_WINDOW_FOREIGN: - was_toplevel = WINDOW_IS_TOPLEVEL (window); + /* Reparenting to toplevel */ + + if (!WINDOW_IS_TOPLEVEL (window) && + GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN) + { + /* This is also done in common code at a later stage, but we + need it in setup_toplevel, so do it here too */ + if (window_private->toplevel_window_type != -1) + GDK_WINDOW_TYPE (window) = window_private->toplevel_window_type; + else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD) + GDK_WINDOW_TYPE (window) = GDK_WINDOW_TOPLEVEL; + + /* Wasn't a toplevel, set up */ + setup_toplevel_window (window, new_parent); + } - if (impl->toplevel_window_type != -1) - GDK_WINDOW_TYPE (window) = impl->toplevel_window_type; - else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD) - GDK_WINDOW_TYPE (window) = GDK_WINDOW_TOPLEVEL; - - if (WINDOW_IS_TOPLEVEL (window) && !was_toplevel) - setup_toplevel_window (window, new_parent); break; + case GDK_WINDOW_TOPLEVEL: case GDK_WINDOW_CHILD: case GDK_WINDOW_DIALOG: case GDK_WINDOW_TEMP: - if (WINDOW_IS_TOPLEVEL (window)) + if (WINDOW_IS_TOPLEVEL (window) && + impl->toplevel) { - /* Save the original window type so we can restore it if the - * window is reparented back to be a toplevel - */ - impl->toplevel_window_type = GDK_WINDOW_TYPE (window); - GDK_WINDOW_TYPE (window) = GDK_WINDOW_CHILD; - if (impl->toplevel) + if (impl->toplevel->focus_window) { - if (impl->toplevel->focus_window) - { - XDestroyWindow (GDK_WINDOW_XDISPLAY (window), impl->toplevel->focus_window); - _gdk_xid_table_remove (GDK_WINDOW_DISPLAY (window), impl->toplevel->focus_window); - } - - gdk_toplevel_x11_free_contents (GDK_WINDOW_DISPLAY (window), - impl->toplevel); - g_free (impl->toplevel); - impl->toplevel = NULL; + XDestroyWindow (GDK_WINDOW_XDISPLAY (window), impl->toplevel->focus_window); + _gdk_xid_table_remove (GDK_WINDOW_DISPLAY (window), impl->toplevel->focus_window); } + + gdk_toplevel_x11_free_contents (GDK_WINDOW_DISPLAY (window), + impl->toplevel); + g_free (impl->toplevel); + impl->toplevel = NULL; } } - if (old_parent_private) - old_parent_private->children = g_list_remove (old_parent_private->children, window); - - if ((old_parent_private && - (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) || - (!old_parent_private && parent_private->guffaw_gravity)) - gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity); - - parent_private->children = g_list_prepend (parent_private->children, window); - _gdk_window_init_position (GDK_WINDOW (window_private)); - return FALSE; } static void -gdk_window_x11_clear_area (GdkWindow *window, - gint x, - gint y, - gint width, - gint height, - gboolean send_expose) +gdk_window_x11_clear_region (GdkWindow *window, + GdkRegion *region, + gboolean send_expose) { - if (!GDK_WINDOW_DESTROYED (window)) + GdkRectangle *rectangles; + int n_rectangles, i; + + gdk_region_get_rectangles (region, + &rectangles, + &n_rectangles); + + for (i = 0; i < n_rectangles; i++) XClearArea (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), - x, y, width, height, - send_expose); + rectangles[i].x, rectangles[i].y, + rectangles[i].width, rectangles[i].height, + send_expose); + + g_free (rectangles); } static void gdk_window_x11_raise (GdkWindow *window) { - if (!GDK_WINDOW_DESTROYED (window)) - XRaiseWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window)); + XRaiseWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window)); +} + +static void +gdk_window_x11_restack_under (GdkWindow *window, + GList *native_siblings /* in requested order, first is bottom-most */) +{ + Window *windows; + int n_windows, i; + GList *l; + + n_windows = g_list_length (native_siblings) + 1; + windows = g_new (Window, n_windows); + + windows[0] = GDK_WINDOW_XID (window); + /* Reverse order, as input order is bottom-most first */ + i = n_windows - 1; + for (l = native_siblings; l != NULL; l = l->next) + windows[i--] = GDK_WINDOW_XID (l->data); + + XRestackWindows (GDK_WINDOW_XDISPLAY (window), windows, n_windows); + + g_free (windows); +} + +static void +gdk_window_x11_restack_toplevel (GdkWindow *window, + GdkWindow *sibling, + gboolean above) +{ + XWindowChanges changes; + + changes.sibling = GDK_WINDOW_XID (sibling); + changes.stack_mode = above ? Above : Below; + XReconfigureWMWindow (GDK_WINDOW_XDISPLAY (window), + GDK_WINDOW_XID (window), + gdk_screen_get_number (GDK_WINDOW_SCREEN (window)), + CWStackMode | CWSibling, &changes); } static void gdk_window_x11_lower (GdkWindow *window) { - if (!GDK_WINDOW_DESTROYED (window)) - XLowerWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window)); + XLowerWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window)); } /** @@ -1957,10 +1834,11 @@ gdk_window_focus (GdkWindow *window, guint32 timestamp) { GdkDisplay *display; - + g_return_if_fail (GDK_IS_WINDOW (window)); - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) return; display = GDK_WINDOW_DISPLAY (window); @@ -2030,9 +1908,8 @@ gdk_window_set_hints (GdkWindow *window, { XSizeHints size_hints; - g_return_if_fail (GDK_IS_WINDOW (window)); - - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) return; size_hints.flags = 0; @@ -2085,9 +1962,8 @@ gdk_window_set_type_hint (GdkWindow *window, GdkDisplay *display; Atom atom; - g_return_if_fail (GDK_IS_WINDOW (window)); - - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) return; display = gdk_drawable_get_display (window); @@ -2170,7 +2046,8 @@ gdk_window_get_type_hint (GdkWindow *window) g_return_val_if_fail (GDK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL); - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) return GDK_WINDOW_TYPE_HINT_NORMAL; type = GDK_WINDOW_TYPE_HINT_NORMAL; @@ -2271,9 +2148,8 @@ gdk_window_set_modal_hint (GdkWindow *window, { GdkWindowObject *private; - g_return_if_fail (GDK_IS_WINDOW (window)); - - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) return; private = (GdkWindowObject*) window; @@ -2306,10 +2182,10 @@ gdk_window_set_skip_taskbar_hint (GdkWindow *window, { GdkToplevelX11 *toplevel; - g_return_if_fail (GDK_IS_WINDOW (window)); g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD); - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) return; toplevel = _gdk_x11_window_get_toplevel (window); @@ -2343,10 +2219,10 @@ gdk_window_set_skip_pager_hint (GdkWindow *window, { GdkToplevelX11 *toplevel; - g_return_if_fail (GDK_IS_WINDOW (window)); g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD); - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) return; toplevel = _gdk_x11_window_get_toplevel (window); @@ -2374,10 +2250,10 @@ gdk_window_set_urgency_hint (GdkWindow *window, { GdkToplevelX11 *toplevel; - g_return_if_fail (GDK_IS_WINDOW (window)); g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD); - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) return; toplevel = _gdk_x11_window_get_toplevel (window); @@ -2422,9 +2298,8 @@ gdk_window_set_geometry_hints (GdkWindow *window, { XSizeHints size_hints; - g_return_if_fail (GDK_IS_WINDOW (window)); - - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) return; size_hints.flags = 0; @@ -2531,7 +2406,8 @@ gdk_window_get_geometry_hints (GdkWindow *window, *geom_mask = 0; - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) return; size_hints = XAllocSizeHints (); @@ -2686,10 +2562,10 @@ gdk_window_set_title (GdkWindow *window, Display *xdisplay; Window xwindow; - g_return_if_fail (GDK_IS_WINDOW (window)); g_return_if_fail (title != NULL); - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) return; display = gdk_drawable_get_display (window); @@ -2735,21 +2611,20 @@ gdk_window_set_role (GdkWindow *window, const gchar *role) { GdkDisplay *display; - - g_return_if_fail (GDK_IS_WINDOW (window)); display = gdk_drawable_get_display (window); - if (!GDK_WINDOW_DESTROYED (window)) - { - if (role) - XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), - gdk_x11_get_xatom_by_name_for_display (display, "WM_WINDOW_ROLE"), - XA_STRING, 8, PropModeReplace, (guchar *)role, strlen (role)); - else - XDeleteProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), - gdk_x11_get_xatom_by_name_for_display (display, "WM_WINDOW_ROLE")); - } + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) + return; + + if (role) + XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), + gdk_x11_get_xatom_by_name_for_display (display, "WM_WINDOW_ROLE"), + XA_STRING, 8, PropModeReplace, (guchar *)role, strlen (role)); + else + XDeleteProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), + gdk_x11_get_xatom_by_name_for_display (display, "WM_WINDOW_ROLE")); } /** @@ -2763,27 +2638,28 @@ gdk_window_set_role (GdkWindow *window, * Since: 2.12 * **/ -void +void gdk_window_set_startup_id (GdkWindow *window, - const gchar *startup_id) + const gchar *startup_id) { GdkDisplay *display; - + g_return_if_fail (GDK_IS_WINDOW (window)); display = gdk_drawable_get_display (window); - if (!GDK_WINDOW_DESTROYED (window)) - { - if (startup_id) - XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), - gdk_x11_get_xatom_by_name_for_display (display, "_NET_STARTUP_ID"), - gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8, - PropModeReplace, startup_id, strlen (startup_id)); - else - XDeleteProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), - gdk_x11_get_xatom_by_name_for_display (display, "_NET_STARTUP_ID")); - } + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) + return; + + if (startup_id) + XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), + gdk_x11_get_xatom_by_name_for_display (display, "_NET_STARTUP_ID"), + gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8, + PropModeReplace, (unsigned char *)startup_id, strlen (startup_id)); + else + XDeleteProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), + gdk_x11_get_xatom_by_name_for_display (display, "_NET_STARTUP_ID")); } /** @@ -2798,15 +2674,13 @@ gdk_window_set_startup_id (GdkWindow *window, * * See gtk_window_set_transient_for() if you're using #GtkWindow or * #GtkDialog. - * **/ -void -gdk_window_set_transient_for (GdkWindow *window, +void +gdk_window_set_transient_for (GdkWindow *window, GdkWindow *parent) { - g_return_if_fail (GDK_IS_WINDOW (window)); - - if (!GDK_WINDOW_DESTROYED (window) && !GDK_WINDOW_DESTROYED (parent)) + if (!GDK_WINDOW_DESTROYED (window) && !GDK_WINDOW_DESTROYED (parent) && + WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) XSetTransientForHint (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), GDK_WINDOW_XID (parent)); @@ -2816,62 +2690,22 @@ static void gdk_window_x11_set_background (GdkWindow *window, const GdkColor *color) { - GdkWindowObject *private = (GdkWindowObject *)window; - GdkColormap *colormap = gdk_drawable_get_colormap (window); - - if (!GDK_WINDOW_DESTROYED (window)) - XSetWindowBackground (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XID (window), color->pixel); - - private->bg_color = *color; - gdk_colormap_query_color (colormap, private->bg_color.pixel, &private->bg_color); - - if (private->bg_pixmap && - private->bg_pixmap != GDK_PARENT_RELATIVE_BG && - private->bg_pixmap != GDK_NO_BG) - g_object_unref (private->bg_pixmap); - - private->bg_pixmap = NULL; + XSetWindowBackground (GDK_WINDOW_XDISPLAY (window), + GDK_WINDOW_XID (window), color->pixel); } static void gdk_window_x11_set_back_pixmap (GdkWindow *window, - GdkPixmap *pixmap, - gboolean parent_relative) + GdkPixmap *pixmap) { - GdkWindowObject *private = (GdkWindowObject *)window; Pixmap xpixmap; - if (pixmap && !gdk_drawable_get_colormap (pixmap)) - { - g_warning ("gdk_window_set_back_pixmap(): pixmap must have a colormap"); - return; - } - - if (private->bg_pixmap && - private->bg_pixmap != GDK_PARENT_RELATIVE_BG && - private->bg_pixmap != GDK_NO_BG) - g_object_unref (private->bg_pixmap); - - if (parent_relative) - { - xpixmap = ParentRelative; - private->bg_pixmap = GDK_PARENT_RELATIVE_BG; - } + if (pixmap == GDK_PARENT_RELATIVE_BG) + xpixmap = ParentRelative; + else if (pixmap == GDK_NO_BG) + xpixmap = None; else - { - if (pixmap) - { - g_object_ref (pixmap); - private->bg_pixmap = pixmap; - xpixmap = GDK_PIXMAP_XID (pixmap); - } - else - { - xpixmap = None; - private->bg_pixmap = GDK_NO_BG; - } - } + xpixmap = GDK_PIXMAP_XID (pixmap); if (!GDK_WINDOW_DESTROYED (window)) XSetWindowBackgroundPixmap (GDK_WINDOW_XDISPLAY (window), @@ -2966,109 +2800,79 @@ gdk_window_x11_get_geometry (GdkWindow *window, } static gint -gdk_window_x11_get_origin (GdkWindow *window, - gint *x, - gint *y) +gdk_window_x11_get_root_coords (GdkWindow *window, + gint x, + gint y, + gint *root_x, + gint *root_y) { gint return_val; Window child; - gint tx = 0; - gint ty = 0; + gint tx; + gint ty; - if (!GDK_WINDOW_DESTROYED (window)) - { - return_val = XTranslateCoordinates (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XID (window), - GDK_WINDOW_XROOTWIN (window), - 0, 0, &tx, &ty, - &child); - } - else - return_val = 0; + return_val = XTranslateCoordinates (GDK_WINDOW_XDISPLAY (window), + GDK_WINDOW_XID (window), + GDK_WINDOW_XROOTWIN (window), + x, y, &tx, &ty, + &child); - if (x) - *x = tx; - if (y) - *y = ty; + if (root_x) + *root_x = tx; + if (root_y) + *root_y = ty; return return_val; } -/** - * gdk_window_get_deskrelative_origin: - * @window: a toplevel #GdkWindow - * @x: return location for X coordinate - * @y: return location for Y coordinate - * - * This gets the origin of a #GdkWindow relative to - * an Enlightenment-window-manager desktop. As long as you don't - * assume that the user's desktop/workspace covers the entire - * root window (i.e. you don't assume that the desktop begins - * at root window coordinate 0,0) this function is not necessary. - * It's deprecated for that reason. - * - * Return value: not meaningful - **/ -gboolean -gdk_window_get_deskrelative_origin (GdkWindow *window, - gint *x, - gint *y) +static gboolean +gdk_window_x11_get_deskrelative_origin (GdkWindow *window, + gint *x, + gint *y) { gboolean return_val = FALSE; gint num_children, format_return; Window win, *child, parent, root; - gint tx = 0; - gint ty = 0; Atom type_return; Atom atom; gulong number_return, bytes_after_return; guchar *data_return; - g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE); + atom = gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window), + "ENLIGHTENMENT_DESKTOP"); + win = GDK_WINDOW_XID (window); - if (!GDK_WINDOW_DESTROYED (window)) + while (XQueryTree (GDK_WINDOW_XDISPLAY (window), win, &root, &parent, + &child, (unsigned int *)&num_children)) { - atom = gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window), - "ENLIGHTENMENT_DESKTOP"); - win = GDK_WINDOW_XID (window); + if ((child) && (num_children > 0)) + XFree (child); - while (XQueryTree (GDK_WINDOW_XDISPLAY (window), win, &root, &parent, - &child, (unsigned int *)&num_children)) + if (!parent) + break; + else + win = parent; + + if (win == root) + break; + + data_return = NULL; + XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), win, atom, 0, 0, + False, XA_CARDINAL, &type_return, &format_return, + &number_return, &bytes_after_return, &data_return); + + if (type_return == XA_CARDINAL) { - if ((child) && (num_children > 0)) - XFree (child); - - if (!parent) - break; - else - win = parent; - - if (win == root) - break; - - data_return = NULL; - XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), win, atom, 0, 0, - False, XA_CARDINAL, &type_return, &format_return, - &number_return, &bytes_after_return, &data_return); - - if (type_return == XA_CARDINAL) - { - XFree (data_return); - break; - } + XFree (data_return); + break; } - - return_val = XTranslateCoordinates (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XID (window), - win, - 0, 0, &tx, &ty, - &root); - if (x) - *x = tx; - if (y) - *y = ty; } + return_val = XTranslateCoordinates (GDK_WINDOW_XDISPLAY (window), + GDK_WINDOW_XID (window), + win, + 0, 0, x, y, + &root); return return_val; } @@ -3090,8 +2894,6 @@ gdk_window_get_root_origin (GdkWindow *window, { GdkRectangle rect; - g_return_if_fail (GDK_IS_WINDOW (window)); - gdk_window_get_frame_extents (window, &rect); if (x) @@ -3136,7 +2938,6 @@ gdk_window_get_frame_extents (GdkWindow *window, gint wx, wy; gboolean got_frame_extents = FALSE; - g_return_if_fail (GDK_IS_WINDOW (window)); g_return_if_fail (rect != NULL); private = (GdkWindowObject*) window; @@ -3146,9 +2947,6 @@ gdk_window_get_frame_extents (GdkWindow *window, rect->width = 1; rect->height = 1; - if (GDK_WINDOW_DESTROYED (window)) - return; - while (private->parent && ((GdkWindowObject*) private->parent)->parent) private = (GdkWindowObject*) private->parent; @@ -3327,55 +3125,53 @@ _gdk_windowing_get_pointer (GdkDisplay *display, *mask = xmask; } -GdkWindow* -_gdk_windowing_window_get_pointer (GdkDisplay *display, - GdkWindow *window, - gint *x, - gint *y, - GdkModifierType *mask) +static gboolean +gdk_window_x11_get_pointer (GdkWindow *window, + gint *x, + gint *y, + GdkModifierType *mask) { - GdkWindow *return_val; + GdkDisplay *display = GDK_WINDOW_DISPLAY (window); + gboolean return_val; Window root; Window child; int rootx, rooty; int winx = 0; int winy = 0; unsigned int xmask = 0; - gint xoffset, yoffset; - g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL); + g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), FALSE); + - _gdk_x11_window_get_offsets (window, &xoffset, &yoffset); - - return_val = NULL; - if (!GDK_WINDOW_DESTROYED (window)) + return_val = TRUE; + if (!GDK_WINDOW_DESTROYED (window)) { - if (G_LIKELY (GDK_DISPLAY_X11 (display)->trusted_client)) + if (G_LIKELY (GDK_DISPLAY_X11 (display)->trusted_client)) { if (XQueryPointer (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), &root, &child, &rootx, &rooty, &winx, &winy, &xmask)) { if (child) - return_val = gdk_window_lookup_for_display (GDK_WINDOW_DISPLAY (window), child); + return_val = gdk_window_lookup_for_display (GDK_WINDOW_DISPLAY (window), child) != NULL; } - } - else + } + else { GdkScreen *screen; int originx, originy; - _gdk_windowing_get_pointer (gdk_drawable_get_display (window), &screen, + _gdk_windowing_get_pointer (gdk_drawable_get_display (window), &screen, &rootx, &rooty, &xmask); gdk_window_get_origin (window, &originx, &originy); winx = rootx - originx; winy = rooty - originy; } } - - *x = winx + xoffset; - *y = winy + yoffset; + + *x = winx; + *y = winy; *mask = xmask; - + return return_val; } @@ -3418,7 +3214,9 @@ gdk_display_warp_pointer (GdkDisplay *display, GdkWindow* _gdk_windowing_window_at_pointer (GdkDisplay *display, gint *win_x, - gint *win_y) + gint *win_y, + GdkModifierType *mask, + gboolean get_toplevel) { GdkWindow *window; GdkScreen *screen; @@ -3454,6 +3252,10 @@ _gdk_windowing_window_at_pointer (GdkDisplay *display, while (xwindow) { xwindow_last = xwindow; + if (get_toplevel && + (window = gdk_window_lookup_for_display (display, xwindow)) != NULL && + GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN) + break; XQueryPointer (xdisplay, xwindow, &root, &xwindow, &rootx, &rooty, &winx, &winy, &xmask); } @@ -3513,6 +3315,10 @@ _gdk_windowing_window_at_pointer (GdkDisplay *display, while (xwindow) { xwindow_last = xwindow; + if (get_toplevel && + (window = gdk_window_lookup_for_display (display, xwindow)) != NULL && + GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN) + break; gdk_error_trap_push (); XQueryPointer (xdisplay, xwindow, &root, &xwindow, &rootx, &rooty, &winx, &winy, &xmask); @@ -3527,7 +3333,9 @@ _gdk_windowing_window_at_pointer (GdkDisplay *display, window = gdk_window_lookup_for_display (display, xwindow_last); *win_x = window ? winx : -1; *win_y = window ? winy : -1; - + if (mask) + *mask = xmask; + return window; } @@ -3562,7 +3370,6 @@ gdk_window_x11_set_events (GdkWindow *window, if (!GDK_WINDOW_DESTROYED (window)) { - GDK_WINDOW_OBJECT (window)->event_mask = event_mask; if (GDK_WINDOW_XID (window) != GDK_WINDOW_XROOTWIN (window)) xevent_mask = StructureNotifyMask | PropertyChangeMask; for (i = 0; i < _gdk_nenvent_masks; i++) @@ -3622,110 +3429,6 @@ gdk_window_add_colormap_windows (GdkWindow *window) XFree (old_windows); } -#define WARN_SHAPE_TOO_BIG() g_warning ("GdkWindow is too large to allow the use of shape masks or shape regions.") - -/* - * This needs the X11 shape extension. - * If not available, shaped windows will look - * ugly, but programs still work. Stefan Wille - */ -static inline void -do_shape_combine_mask (GdkWindow *window, - GdkBitmap *mask, - gint x, - gint y, - gint shape) -{ - GdkWindowObject *private = (GdkWindowObject *)window; - Pixmap pixmap; - gint xoffset, yoffset; - - if (GDK_WINDOW_DESTROYED (window)) - return; - - _gdk_x11_window_get_offsets (window, &xoffset, &yoffset); - - if (xoffset != 0 || yoffset != 0) - { - WARN_SHAPE_TOO_BIG (); - return; - } - - if (shape == ShapeBounding - ? gdk_display_supports_shapes (GDK_WINDOW_DISPLAY (window)) - : gdk_display_supports_input_shapes (GDK_WINDOW_DISPLAY (window))) - { - if (mask) - { - pixmap = GDK_PIXMAP_XID (mask); - - private->shaped = (shape == ShapeBounding); - } - else - { - x = 0; - y = 0; - pixmap = None; - - private->shaped = FALSE; - } - - XShapeCombineMask (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XID (window), - shape, - x, y, - pixmap, - ShapeSet); - } -} - -static void -gdk_window_x11_shape_combine_mask (GdkWindow *window, - GdkBitmap *mask, - gint x, - gint y) -{ - do_shape_combine_mask (window, mask, x, y, ShapeBounding); -} - -/** - * gdk_window_input_shape_combine_mask: - * @window: a #GdkWindow - * @mask: shape mask - * @x: X position of shape mask with respect to @window - * @y: Y position of shape mask with respect to @window - * - * Like gdk_window_shape_combine_mask(), but the shape applies - * only to event handling. Mouse events which happen while - * the pointer position corresponds to an unset bit in the - * mask will be passed on the window below @window. - * - * An input shape is typically used with RGBA windows. - * The alpha channel of the window defines which pixels are - * invisible and allows for nicely antialiased borders, - * and the input shape controls where the window is - * "clickable". - * - * On the X11 platform, this requires version 1.1 of the - * shape extension. - * - * On the Win32 platform, this functionality is not present and the - * function does nothing. - * - * Since: 2.10 - */ -void -gdk_window_input_shape_combine_mask (GdkWindow *window, - GdkBitmap *mask, - gint x, - gint y) -{ -#ifdef ShapeInput - do_shape_combine_mask (window, mask, x, y, ShapeInput); -#endif -} - - static inline void do_shape_combine_region (GdkWindow *window, const GdkRegion *shape_region, @@ -3734,23 +3437,34 @@ do_shape_combine_region (GdkWindow *window, gint shape) { GdkWindowObject *private = (GdkWindowObject *)window; - gint xoffset, yoffset; - + if (GDK_WINDOW_DESTROYED (window)) return; - _gdk_x11_window_get_offsets (window, &xoffset, &yoffset); - - if (xoffset != 0 || yoffset != 0) - { - WARN_SHAPE_TOO_BIG (); - return; - } - if (shape_region == NULL) { /* Use NULL mask to unset the shape */ - gdk_window_shape_combine_mask (window, NULL, 0, 0); + if (shape == ShapeBounding + ? gdk_display_supports_shapes (GDK_WINDOW_DISPLAY (window)) + : gdk_display_supports_input_shapes (GDK_WINDOW_DISPLAY (window))) + { + if (shape == ShapeBounding) + { + _gdk_x11_window_tmp_unset_parent_bg (window); + _gdk_x11_window_tmp_unset_bg (window, TRUE); + } + XShapeCombineMask (GDK_WINDOW_XDISPLAY (window), + GDK_WINDOW_XID (window), + shape, + 0, 0, + None, + ShapeSet); + if (shape == ShapeBounding) + { + _gdk_x11_window_tmp_reset_parent_bg (window); + _gdk_x11_window_tmp_reset_bg (window, TRUE); + } + } return; } @@ -3761,12 +3475,15 @@ do_shape_combine_region (GdkWindow *window, gint n_rects = 0; XRectangle *xrects = NULL; - private->shaped = shape == ShapeBounding; - _gdk_region_get_xrectangles (shape_region, 0, 0, &xrects, &n_rects); + if (shape == ShapeBounding) + { + _gdk_x11_window_tmp_unset_parent_bg (window); + _gdk_x11_window_tmp_unset_bg (window, TRUE); + } XShapeCombineRectangles (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), shape, @@ -3775,6 +3492,12 @@ do_shape_combine_region (GdkWindow *window, ShapeSet, YXBanded); + if (shape == ShapeBounding) + { + _gdk_x11_window_tmp_reset_parent_bg (window); + _gdk_x11_window_tmp_reset_bg (window, TRUE); + } + g_free (xrects); } } @@ -3788,37 +3511,11 @@ gdk_window_x11_shape_combine_region (GdkWindow *window, do_shape_combine_region (window, shape_region, offset_x, offset_y, ShapeBounding); } -/** - * gdk_window_input_shape_combine_region: - * @window: a #GdkWindow - * @shape_region: region of window to be non-transparent - * @offset_x: X position of @shape_region in @window coordinates - * @offset_y: Y position of @shape_region in @window coordinates - * - * Like gdk_window_shape_combine_region(), but the shape applies - * only to event handling. Mouse events which happen while - * the pointer position corresponds to an unset bit in the - * mask will be passed on the window below @window. - * - * An input shape is typically used with RGBA windows. - * The alpha channel of the window defines which pixels are - * invisible and allows for nicely antialiased borders, - * and the input shape controls where the window is - * "clickable". - * - * On the X11 platform, this requires version 1.1 of the - * shape extension. - * - * On the Win32 platform, this functionality is not present and the - * function does nothing. - * - * Since: 2.10 - */ -void -gdk_window_input_shape_combine_region (GdkWindow *window, - const GdkRegion *shape_region, - gint offset_x, - gint offset_y) +static void +gdk_window_x11_input_shape_combine_region (GdkWindow *window, + const GdkRegion *shape_region, + gint offset_x, + gint offset_y) { #ifdef ShapeInput do_shape_combine_region (window, shape_region, offset_x, offset_y, ShapeInput); @@ -3847,9 +3544,8 @@ gdk_window_set_override_redirect (GdkWindow *window, { XSetWindowAttributes attr; - g_return_if_fail (GDK_IS_WINDOW (window)); - - if (!GDK_WINDOW_DESTROYED (window)) + if (!GDK_WINDOW_DESTROYED (window) && + WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) { GdkWindowObject *private = (GdkWindowObject *)window; GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl); @@ -3883,8 +3579,6 @@ gdk_window_set_accept_focus (GdkWindow *window, { GdkWindowObject *private; - g_return_if_fail (GDK_IS_WINDOW (window)); - private = (GdkWindowObject *)window; accept_focus = accept_focus != FALSE; @@ -3893,7 +3587,8 @@ gdk_window_set_accept_focus (GdkWindow *window, { private->accept_focus = accept_focus; - if (!GDK_WINDOW_DESTROYED (window)) + if (!GDK_WINDOW_DESTROYED (window) && + WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) update_wm_hints (window, FALSE); } } @@ -3920,8 +3615,6 @@ gdk_window_set_focus_on_map (GdkWindow *window, { GdkWindowObject *private; - g_return_if_fail (GDK_IS_WINDOW (window)); - private = (GdkWindowObject *)window; focus_on_map = focus_on_map != FALSE; @@ -3929,8 +3622,10 @@ gdk_window_set_focus_on_map (GdkWindow *window, if (private->focus_on_map != focus_on_map) { private->focus_on_map = focus_on_map; - - if ((!GDK_WINDOW_DESTROYED (window)) && (!private->focus_on_map)) + + if ((!GDK_WINDOW_DESTROYED (window)) && + (!private->focus_on_map) && + WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) gdk_x11_window_set_user_time (window, 0); } } @@ -3965,9 +3660,8 @@ gdk_x11_window_set_user_time (GdkWindow *window, glong timestamp_long = (glong)timestamp; Window xid; - g_return_if_fail (GDK_IS_WINDOW (window)); - - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) return; display = gdk_drawable_get_display (window); @@ -4037,9 +3731,8 @@ gdk_window_set_icon_list (GdkWindow *window, GdkDisplay *display; gint n; - g_return_if_fail (GDK_IS_WINDOW (window)); - - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) return; display = gdk_drawable_get_display (window); @@ -4149,10 +3842,8 @@ gdk_window_set_icon (GdkWindow *window, { GdkToplevelX11 *toplevel; - g_return_if_fail (GDK_IS_WINDOW (window)); - g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD); - - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) return; toplevel = _gdk_x11_window_get_toplevel (window); @@ -4214,9 +3905,8 @@ gdk_window_set_icon_name (GdkWindow *window, { GdkDisplay *display; - g_return_if_fail (GDK_IS_WINDOW (window)); - - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) return; display = gdk_drawable_get_display (window); @@ -4261,9 +3951,8 @@ gdk_window_set_icon_name (GdkWindow *window, void gdk_window_iconify (GdkWindow *window) { - g_return_if_fail (GDK_IS_WINDOW (window)); - - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) return; if (GDK_WINDOW_IS_MAPPED (window)) @@ -4295,9 +3984,8 @@ gdk_window_iconify (GdkWindow *window) void gdk_window_deiconify (GdkWindow *window) { - g_return_if_fail (GDK_IS_WINDOW (window)); - - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) return; if (GDK_WINDOW_IS_MAPPED (window)) @@ -4331,9 +4019,8 @@ gdk_window_deiconify (GdkWindow *window) void gdk_window_stick (GdkWindow *window) { - g_return_if_fail (GDK_IS_WINDOW (window)); - - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) return; if (GDK_WINDOW_IS_MAPPED (window)) @@ -4388,9 +4075,8 @@ gdk_window_stick (GdkWindow *window) void gdk_window_unstick (GdkWindow *window) { - g_return_if_fail (GDK_IS_WINDOW (window)); - - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) return; if (GDK_WINDOW_IS_MAPPED (window)) @@ -4432,9 +4118,8 @@ gdk_window_unstick (GdkWindow *window) void gdk_window_maximize (GdkWindow *window) { - g_return_if_fail (GDK_IS_WINDOW (window)); - - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) return; if (GDK_WINDOW_IS_MAPPED (window)) @@ -4467,9 +4152,8 @@ gdk_window_maximize (GdkWindow *window) void gdk_window_unmaximize (GdkWindow *window) { - g_return_if_fail (GDK_IS_WINDOW (window)); - - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) return; if (GDK_WINDOW_IS_MAPPED (window)) @@ -4505,9 +4189,8 @@ gdk_window_unmaximize (GdkWindow *window) void gdk_window_fullscreen (GdkWindow *window) { - g_return_if_fail (GDK_IS_WINDOW (window)); - - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) return; if (GDK_WINDOW_IS_MAPPED (window)) @@ -4541,9 +4224,8 @@ gdk_window_fullscreen (GdkWindow *window) void gdk_window_unfullscreen (GdkWindow *window) { - g_return_if_fail (GDK_IS_WINDOW (window)); - - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) return; if (GDK_WINDOW_IS_MAPPED (window)) @@ -4580,7 +4262,8 @@ gdk_window_set_keep_above (GdkWindow *window, { g_return_if_fail (GDK_IS_WINDOW (window)); - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) return; if (GDK_WINDOW_IS_MAPPED (window)) @@ -4621,7 +4304,8 @@ gdk_window_set_keep_below (GdkWindow *window, gboolean setting) { g_return_if_fail (GDK_IS_WINDOW (window)); - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) return; if (GDK_WINDOW_IS_MAPPED (window)) @@ -4655,10 +4339,8 @@ gdk_window_get_group (GdkWindow *window) { GdkToplevelX11 *toplevel; - g_return_val_if_fail (GDK_IS_WINDOW (window), NULL); - g_return_val_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD, NULL); - - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL (window)) return NULL; toplevel = _gdk_x11_window_get_toplevel (window); @@ -4683,7 +4365,7 @@ gdk_window_get_group (GdkWindow *window) * if your application pretends to be multiple applications. **/ void -gdk_window_set_group (GdkWindow *window, +gdk_window_set_group (GdkWindow *window, GdkWindow *leader) { GdkToplevelX11 *toplevel; @@ -4692,12 +4374,14 @@ gdk_window_set_group (GdkWindow *window, g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD); g_return_if_fail (leader == NULL || GDK_IS_WINDOW (leader)); - if (GDK_WINDOW_DESTROYED (window) || (leader != NULL && GDK_WINDOW_DESTROYED (leader))) + if (GDK_WINDOW_DESTROYED (window) || + (leader != NULL && GDK_WINDOW_DESTROYED (leader)) || + !WINDOW_IS_TOPLEVEL (window)) return; toplevel = _gdk_x11_window_get_toplevel (window); - if (leader == NULL) + if (leader == NULL) leader = gdk_display_get_default_group (gdk_drawable_get_display (window)); if (toplevel->group_leader != leader) @@ -4817,8 +4501,10 @@ gdk_window_set_decorations (GdkWindow *window, GdkWMDecoration decorations) { MotifWmHints hints; - - g_return_if_fail (GDK_IS_WINDOW (window)); + + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) + return; /* initialize to zero to avoid writing uninitialized data to socket */ memset(&hints, 0, sizeof(hints)); @@ -4843,8 +4529,10 @@ gdk_window_get_decorations(GdkWindow *window, MotifWmHints *hints; gboolean result = FALSE; - g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE); - + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) + return FALSE; + hints = gdk_window_get_mwm_hints (window); if (hints) @@ -4889,6 +4577,10 @@ gdk_window_set_functions (GdkWindow *window, MotifWmHints hints; g_return_if_fail (GDK_IS_WINDOW (window)); + + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) + return; /* initialize to zero to avoid writing uninitialized data to socket */ memset(&hints, 0, sizeof(hints)); @@ -4898,404 +4590,105 @@ gdk_window_set_functions (GdkWindow *window, gdk_window_set_mwm_hints (window, &hints); } -/* - * propagate the shapes from all child windows of a GDK window to the parent - * window. Shamelessly ripped from Enlightenment's code - * - * - Raster - */ -struct _gdk_span +static GdkRegion * +xwindow_get_shape (Display *xdisplay, + Window window, + gint shape_type) { - gint start; - gint end; - struct _gdk_span *next; -}; + GdkRegion *shape; + GdkRectangle *rl; + XRectangle *xrl; + gint rn, ord, i; -static void -gdk_add_to_span (struct _gdk_span **s, - gint x, - gint xx) -{ - struct _gdk_span *ptr1, *ptr2, *noo, *ss; - gchar spanning; + shape = NULL; - ptr2 = NULL; - ptr1 = *s; - spanning = 0; - ss = NULL; - /* scan the spans for this line */ - while (ptr1) - { - /* -- -> new span */ - /* == -> existing span */ - /* ## -> spans intersect */ - /* if we are in the middle of spanning the span into the line */ - if (spanning) - { - /* case: ---- ==== */ - if (xx < ptr1->start - 1) - { - /* ends before next span - extend to here */ - ss->end = xx; - return; - } - /* case: ----##=== */ - else if (xx <= ptr1->end) - { - /* crosses into next span - delete next span and append */ - ss->end = ptr1->end; - ss->next = ptr1->next; - g_free (ptr1); - return; - } - /* case: ---###--- */ - else - { - /* overlaps next span - delete and keep checking */ - ss->next = ptr1->next; - g_free (ptr1); - ptr1 = ss; - } - } - /* otherwise havent started spanning it in yet */ - else - { - /* case: ---- ==== */ - if (xx < ptr1->start - 1) - { - /* insert span here in list */ - noo = g_malloc (sizeof (struct _gdk_span)); - - if (noo) - { - noo->start = x; - noo->end = xx; - noo->next = ptr1; - if (ptr2) - ptr2->next = noo; - else - *s = noo; - } - return; - } - /* case: ----##=== */ - else if ((x < ptr1->start) && (xx <= ptr1->end)) - { - /* expand this span to the left point of the new one */ - ptr1->start = x; - return; - } - /* case: ===###=== */ - else if ((x >= ptr1->start) && (xx <= ptr1->end)) - { - /* throw the span away */ - return; - } - /* case: ---###--- */ - else if ((x < ptr1->start) && (xx > ptr1->end)) - { - ss = ptr1; - spanning = 1; - ptr1->start = x; - ptr1->end = xx; - } - /* case: ===##---- */ - else if ((x >= ptr1->start) && (x <= ptr1->end + 1) && (xx > ptr1->end)) - { - ss = ptr1; - spanning = 1; - ptr1->end = xx; - } - /* case: ==== ---- */ - /* case handled by next loop iteration - first case */ - } - ptr2 = ptr1; - ptr1 = ptr1->next; - } - /* it started in the middle but spans beyond your current list */ - if (spanning) - { - ptr2->end = xx; - return; - } - /* it does not start inside a span or in the middle, so add it to the end */ - noo = g_malloc (sizeof (struct _gdk_span)); + xrl = XShapeGetRectangles (xdisplay, + window, + shape_type, &rn, &ord); - if (noo) + if (rn == 0) + return gdk_region_new (); /* Empty */ + + if (ord != YXBanded) { - noo->start = x; - noo->end = xx; - if (ptr2) - { - noo->next = ptr2->next; - ptr2->next = noo; - } - else - { - noo->next = NULL; - *s = noo; - } + /* This really shouldn't happen with any xserver, as they + generally convert regions to YXBanded internally */ + g_warning ("non YXBanded shape masks not supported"); + XFree (xrl); + return NULL; } - return; + + rl = g_new (GdkRectangle, rn); + for (i = 0; i < rn; i++) + { + rl[i].x = xrl[i].x; + rl[i].y = xrl[i].y; + rl[i].width = xrl[i].width; + rl[i].height = xrl[i].height; + } + XFree (xrl); + + shape = _gdk_region_new_from_yxbanded_rects (rl, rn); + g_free (rl); + + return shape; } -static void -gdk_add_rectangles (Display *disp, - Window win, - struct _gdk_span **spans, - gint basew, - gint baseh, - gint x, - gint y) + +GdkRegion * +_gdk_windowing_get_shape_for_mask (GdkBitmap *mask) { - gint a, k; - gint x1, y1, x2, y2; - gint rn, ord; - XRectangle *rl; + GdkDisplay *display; + Window window; + GdkRegion *region; + + display = gdk_drawable_get_display (GDK_DRAWABLE (mask)); + + window = XCreateSimpleWindow (GDK_DISPLAY_XDISPLAY (display), + GDK_SCREEN_XROOTWIN (gdk_display_get_default_screen (display)), + -1, -1, 1, 1, 0, + 0, 0); + XShapeCombineMask (GDK_DISPLAY_XDISPLAY (display), + window, + ShapeBounding, + 0, 0, + GDK_PIXMAP_XID (mask), + ShapeSet); - rl = XShapeGetRectangles (disp, win, ShapeBounding, &rn, &ord); - if (rl) - { - /* go through all clip rects in this window's shape */ - for (k = 0; k < rn; k++) - { - /* for each clip rect, add it to each line's spans */ - x1 = x + rl[k].x; - x2 = x + rl[k].x + (rl[k].width - 1); - y1 = y + rl[k].y; - y2 = y + rl[k].y + (rl[k].height - 1); - if (x1 < 0) - x1 = 0; - if (y1 < 0) - y1 = 0; - if (x2 >= basew) - x2 = basew - 1; - if (y2 >= baseh) - y2 = baseh - 1; - for (a = y1; a <= y2; a++) - { - if ((x2 - x1) >= 0) - gdk_add_to_span (&spans[a], x1, x2); - } - } - XFree (rl); - } + region = xwindow_get_shape (GDK_DISPLAY_XDISPLAY (display), + window, ShapeBounding); + + XDestroyWindow (GDK_DISPLAY_XDISPLAY (display), + window); + + return region; } -static void -gdk_propagate_shapes (Display *disp, - Window win, - gboolean merge, - int shape) -{ - Window rt, par, *list = NULL; - gint i, j, num = 0, num_rects = 0; - gint x, y, contig; - guint w, h, d; - gint baseh, basew; - XRectangle *rects = NULL; - struct _gdk_span **spans = NULL, *ptr1, *ptr2, *ptr3; - XWindowAttributes xatt; - - XGetGeometry (disp, win, &rt, &x, &y, &w, &h, &d, &d); - if (h <= 0) - return; - basew = w; - baseh = h; - spans = g_malloc (sizeof (struct _gdk_span *) * h); - - for (i = 0; i < h; i++) - spans[i] = NULL; - XQueryTree (disp, win, &rt, &par, &list, (unsigned int *)&num); - if (list) - { - /* go through all child windows and create/insert spans */ - for (i = 0; i < num; i++) - { - if (XGetWindowAttributes (disp, list[i], &xatt) && (xatt.map_state != IsUnmapped)) - if (XGetGeometry (disp, list[i], &rt, &x, &y, &w, &h, &d, &d)) - gdk_add_rectangles (disp, list[i], spans, basew, baseh, x, y); - } - if (merge) - gdk_add_rectangles (disp, win, spans, basew, baseh, x, y); - - /* go through the spans list and build a list of rects */ - rects = g_malloc (sizeof (XRectangle) * 256); - num_rects = 0; - for (i = 0; i < baseh; i++) - { - ptr1 = spans[i]; - /* go through the line for all spans */ - while (ptr1) - { - rects[num_rects].x = ptr1->start; - rects[num_rects].y = i; - rects[num_rects].width = ptr1->end - ptr1->start + 1; - rects[num_rects].height = 1; - j = i + 1; - /* if there are more lines */ - contig = 1; - /* while contigous rects (same start/end coords) exist */ - while ((contig) && (j < baseh)) - { - /* search next line for spans matching this one */ - contig = 0; - ptr2 = spans[j]; - ptr3 = NULL; - while (ptr2) - { - /* if we have an exact span match set contig */ - if ((ptr2->start == ptr1->start) && - (ptr2->end == ptr1->end)) - { - contig = 1; - /* remove the span - not needed */ - if (ptr3) - { - ptr3->next = ptr2->next; - g_free (ptr2); - ptr2 = NULL; - } - else - { - spans[j] = ptr2->next; - g_free (ptr2); - ptr2 = NULL; - } - break; - } - /* gone past the span point no point looking */ - else if (ptr2->start < ptr1->start) - break; - if (ptr2) - { - ptr3 = ptr2; - ptr2 = ptr2->next; - } - } - /* if a contiguous span was found increase the rect h */ - if (contig) - { - rects[num_rects].height++; - j++; - } - } - /* up the rect count */ - num_rects++; - /* every 256 new rects increase the rect array */ - if ((num_rects % 256) == 0) - rects = g_realloc (rects, sizeof (XRectangle) * (num_rects + 256)); - ptr1 = ptr1->next; - } - } - /* set the rects as the shape mask */ - if (rects) - { - XShapeCombineRectangles (disp, win, shape, 0, 0, rects, num_rects, - ShapeSet, YXSorted); - g_free (rects); - } - XFree (list); - } - /* free up all the spans we made */ - for (i = 0; i < baseh; i++) - { - ptr1 = spans[i]; - while (ptr1) - { - ptr2 = ptr1; - ptr1 = ptr1->next; - g_free (ptr2); - } - } - g_free (spans); -} - -static inline void -do_child_shapes (GdkWindow *window, - gboolean merge) +GdkRegion * +_gdk_windowing_window_get_shape (GdkWindow *window) { if (!GDK_WINDOW_DESTROYED (window) && gdk_display_supports_shapes (GDK_WINDOW_DISPLAY (window))) - { - gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XID (window), - merge, - ShapeBounding); - } + return xwindow_get_shape (GDK_WINDOW_XDISPLAY (window), + GDK_WINDOW_XID (window), ShapeBounding); + + return NULL; } -static void -gdk_window_x11_set_child_shapes (GdkWindow *window) -{ - do_child_shapes (window, FALSE); -} - -static void -gdk_window_x11_merge_child_shapes (GdkWindow *window) -{ - do_child_shapes (window, TRUE); -} - -static inline void -do_child_input_shapes (GdkWindow *window, - gboolean merge) +GdkRegion * +_gdk_windowing_window_get_input_shape (GdkWindow *window) { #if defined(ShapeInput) if (!GDK_WINDOW_DESTROYED (window) && gdk_display_supports_shapes (GDK_WINDOW_DISPLAY (window))) - { - gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XID (window), - merge, - ShapeInput); - } + return xwindow_get_shape (GDK_WINDOW_XDISPLAY (window), + GDK_WINDOW_XID (window), + ShapeInput); #endif -} -/** - * gdk_window_set_child_input_shapes: - * @window: a #GdkWindow - * - * Sets the input shape mask of @window to the union of input shape masks - * for all children of @window, ignoring the input shape mask of @window - * itself. Contrast with gdk_window_merge_child_input_shapes() which includes - * the input shape mask of @window in the masks to be merged. - * - * Since: 2.10 - **/ -void -gdk_window_set_child_input_shapes (GdkWindow *window) -{ - g_return_if_fail (GDK_IS_WINDOW (window)); - - do_child_input_shapes (window, FALSE); + return NULL; } -/** - * gdk_window_merge_child_input_shapes: - * @window: a #GdkWindow - * - * Merges the input shape masks for any child windows into the - * input shape mask for @window. i.e. the union of all input masks - * for @window and its children will become the new input mask - * for @window. See gdk_window_input_shape_combine_mask(). - * - * This function is distinct from gdk_window_set_child_input_shapes() - * because it includes @window's input shape mask in the set of - * shapes to be merged. - * - * Since: 2.10 - **/ -void -gdk_window_merge_child_input_shapes (GdkWindow *window) -{ - g_return_if_fail (GDK_IS_WINDOW (window)); - - do_child_input_shapes (window, TRUE); -} - - static void gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on) @@ -5927,9 +5320,8 @@ gdk_window_begin_resize_drag (GdkWindow *window, gint root_y, guint32 timestamp) { - g_return_if_fail (GDK_IS_WINDOW (window)); - - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) return; if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window), @@ -5962,9 +5354,8 @@ gdk_window_begin_move_drag (GdkWindow *window, gint root_y, guint32 timestamp) { - g_return_if_fail (GDK_IS_WINDOW (window)); - - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL (window)) return; if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window), @@ -5998,12 +5389,17 @@ gdk_window_enable_synchronized_configure (GdkWindow *window) GdkWindowObject *private = (GdkWindowObject *)window; GdkWindowImplX11 *impl; - g_return_if_fail (GDK_IS_WINDOW (window)); - + if (!GDK_IS_WINDOW_IMPL_X11 (private->impl)) + return; + impl = GDK_WINDOW_IMPL_X11 (private->impl); if (!impl->use_synchronized_configure) { + /* This basically means you want to do fancy X specific stuff, so + ensure we have a native window */ + gdk_window_ensure_native (window); + impl->use_synchronized_configure = TRUE; ensure_sync_counter (window); } @@ -6029,7 +5425,8 @@ gdk_window_configure_finished (GdkWindow *window) { GdkWindowImplX11 *impl; - g_return_if_fail (GDK_IS_WINDOW (window)); + if (!WINDOW_IS_TOPLEVEL (window)) + return; impl = GDK_WINDOW_IMPL_X11 (((GdkWindowObject *)window)->impl); if (!impl->use_synchronized_configure) @@ -6055,21 +5452,13 @@ gdk_window_configure_finished (GdkWindow *window) #endif } -/** - * gdk_window_beep: - * @window: a toplevel #GdkWindow - * - * Emits a short beep associated to @window in the appropriate - * display, if supported. Otherwise, emits a short beep on - * the display just as gdk_display_beep(). - * - * Since: 2.12 - **/ void -gdk_window_beep (GdkWindow *window) +_gdk_windowing_window_beep (GdkWindow *window) { GdkDisplay *display; + g_return_if_fail (GDK_IS_WINDOW (window)); + display = GDK_WINDOW_DISPLAY (window); #ifdef HAVE_XKB @@ -6109,9 +5498,9 @@ gdk_window_set_opacity (GdkWindow *window, guint32 cardinal; g_return_if_fail (GDK_IS_WINDOW (window)); - g_return_if_fail (WINDOW_IS_TOPLEVEL (window)); - if (GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window) || + !WINDOW_IS_TOPLEVEL (window)) return; display = gdk_drawable_get_display (window); @@ -6142,7 +5531,6 @@ _gdk_windowing_window_set_composited (GdkWindow *window, { #if defined(HAVE_XCOMPOSITE) && defined(HAVE_XDAMAGE) && defined (HAVE_XFIXES) GdkWindowObject *private = (GdkWindowObject *) window; - GdkDisplayX11 *x11_display; GdkWindowImplX11 *impl; GdkDisplay *display; Display *dpy; @@ -6151,7 +5539,6 @@ _gdk_windowing_window_set_composited (GdkWindow *window, impl = GDK_WINDOW_IMPL_X11 (private->impl); display = gdk_screen_get_display (GDK_DRAWABLE_IMPL_X11 (impl)->screen); - x11_display = GDK_DISPLAY_X11 (display); dpy = GDK_DISPLAY_XDISPLAY (display); xid = GDK_WINDOW_XWINDOW (private); @@ -6169,6 +5556,23 @@ _gdk_windowing_window_set_composited (GdkWindow *window, #endif } +void +_gdk_windowing_window_process_updates_recurse (GdkWindow *window, + GdkRegion *region) +{ + _gdk_window_process_updates_recurse (window, region); +} + +void +_gdk_windowing_before_process_all_updates (void) +{ +} + +void +_gdk_windowing_after_process_all_updates (void) +{ +} + static void gdk_window_impl_iface_init (GdkWindowImplIface *iface) { @@ -6177,24 +5581,28 @@ gdk_window_impl_iface_init (GdkWindowImplIface *iface) iface->withdraw = gdk_window_x11_withdraw; iface->set_events = gdk_window_x11_set_events; iface->get_events = gdk_window_x11_get_events; - iface->clear_area = gdk_window_x11_clear_area; iface->raise = gdk_window_x11_raise; iface->lower = gdk_window_x11_lower; + iface->restack_under = gdk_window_x11_restack_under; + iface->restack_toplevel = gdk_window_x11_restack_toplevel; iface->move_resize = gdk_window_x11_move_resize; - iface->scroll = _gdk_x11_window_scroll; - iface->move_region = _gdk_x11_window_move_region; iface->set_background = gdk_window_x11_set_background; iface->set_back_pixmap = gdk_window_x11_set_back_pixmap; iface->reparent = gdk_window_x11_reparent; + iface->clear_region = gdk_window_x11_clear_region; iface->set_cursor = gdk_window_x11_set_cursor; iface->get_geometry = gdk_window_x11_get_geometry; - iface->get_origin = gdk_window_x11_get_origin; - iface->shape_combine_mask = gdk_window_x11_shape_combine_mask; + iface->get_root_coords = gdk_window_x11_get_root_coords; + iface->get_pointer = gdk_window_x11_get_pointer; + iface->get_deskrelative_origin = gdk_window_x11_get_deskrelative_origin; iface->shape_combine_region = gdk_window_x11_shape_combine_region; - iface->set_child_shapes = gdk_window_x11_set_child_shapes; - iface->merge_child_shapes = gdk_window_x11_merge_child_shapes; + iface->input_shape_combine_region = gdk_window_x11_input_shape_combine_region; iface->set_static_gravities = gdk_window_x11_set_static_gravities; - iface->get_offsets = _gdk_x11_window_get_offsets; + iface->queue_antiexpose = _gdk_x11_window_queue_antiexpose; + iface->queue_translation = _gdk_x11_window_queue_translation; + iface->destroy = _gdk_x11_window_destroy; + iface->input_window_destroy = _gdk_input_window_destroy; + iface->input_window_crossing = _gdk_input_crossing_event; } #define __GDK_WINDOW_X11_C__ diff --git a/gdk/x11/gdkwindow-x11.h b/gdk/x11/gdkwindow-x11.h index 2a2799b079..9a7f2aed35 100644 --- a/gdk/x11/gdkwindow-x11.h +++ b/gdk/x11/gdkwindow-x11.h @@ -44,22 +44,6 @@ typedef struct _GdkWindowImplX11 GdkWindowImplX11; typedef struct _GdkWindowImplX11Class GdkWindowImplX11Class; typedef struct _GdkXPositionInfo GdkXPositionInfo; -struct _GdkXPositionInfo -{ - gint x; - gint y; - gint width; - gint height; - gint x_offset; /* Offsets to add to X coordinates within window */ - gint y_offset; /* to get GDK coodinates within window */ - guint big : 1; - guint mapped : 1; - guint no_bg : 1; /* Set when the window background is temporarily - * unset during resizing and scaling */ - GdkRectangle clip_rect; /* visible rectangle of window */ -}; - - /* Window implementation for X11 */ @@ -74,13 +58,11 @@ struct _GdkWindowImplX11 { GdkDrawableImplX11 parent_instance; - gint width; - gint height; - - GdkXPositionInfo position_info; GdkToplevelX11 *toplevel; /* Toplevel-specific information */ GdkCursor *cursor; gint8 toplevel_window_type; + guint no_bg : 1; /* Set when the window background is temporarily + * unset during resizing and scaling */ guint override_redirect : 1; guint use_synchronized_configure : 1; @@ -158,15 +140,16 @@ struct _GdkToplevelX11 GType gdk_window_impl_x11_get_type (void); -void gdk_x11_window_set_user_time (GdkWindow *window, - guint32 timestamp); - -GdkToplevelX11 *_gdk_x11_window_get_toplevel (GdkWindow *window); -void _gdk_x11_window_tmp_unset_bg (GdkWindow *window, - gboolean recurse); -void _gdk_x11_window_tmp_reset_bg (GdkWindow *window, - gboolean recurse); +void gdk_x11_window_set_user_time (GdkWindow *window, + guint32 timestamp); +GdkToplevelX11 *_gdk_x11_window_get_toplevel (GdkWindow *window); +void _gdk_x11_window_tmp_unset_bg (GdkWindow *window, + gboolean recurse); +void _gdk_x11_window_tmp_reset_bg (GdkWindow *window, + gboolean recurse); +void _gdk_x11_window_tmp_unset_parent_bg (GdkWindow *window); +void _gdk_x11_window_tmp_reset_parent_bg (GdkWindow *window); GdkCursor *_gdk_x11_window_get_cursor (GdkWindow *window); void _gdk_x11_window_get_offsets (GdkWindow *window, diff --git a/gdk/x11/gdkx.h b/gdk/x11/gdkx.h index baa395d392..d8aa42c843 100644 --- a/gdk/x11/gdkx.h +++ b/gdk/x11/gdkx.h @@ -40,6 +40,8 @@ extern Display *gdk_display; Display *gdk_x11_drawable_get_xdisplay (GdkDrawable *drawable); XID gdk_x11_drawable_get_xid (GdkDrawable *drawable); +GdkDrawable *gdk_x11_window_get_drawable_impl (GdkWindow *window); +GdkDrawable *gdk_x11_pixmap_get_drawable_impl (GdkPixmap *pixmap); Display *gdk_x11_image_get_xdisplay (GdkImage *image); XImage *gdk_x11_image_get_ximage (GdkImage *image); Display *gdk_x11_colormap_get_xdisplay (GdkColormap *colormap); @@ -105,10 +107,10 @@ gint gdk_x11_get_default_screen (void); #define GDK_DISPLAY_XDISPLAY(display) (gdk_x11_display_get_xdisplay (display)) -#define GDK_WINDOW_XDISPLAY(win) (gdk_x11_drawable_get_xdisplay (((GdkWindowObject *)win)->impl)) +#define GDK_WINDOW_XDISPLAY(win) (gdk_x11_drawable_get_xdisplay (gdk_x11_window_get_drawable_impl (win))) #define GDK_WINDOW_XID(win) (gdk_x11_drawable_get_xid (win)) #define GDK_WINDOW_XWINDOW(win) (gdk_x11_drawable_get_xid (win)) -#define GDK_PIXMAP_XDISPLAY(win) (gdk_x11_drawable_get_xdisplay (((GdkPixmapObject *)win)->impl)) +#define GDK_PIXMAP_XDISPLAY(win) (gdk_x11_drawable_get_xdisplay (gdk_x11_pixmap_get_drawable_impl (win))) #define GDK_PIXMAP_XID(win) (gdk_x11_drawable_get_xid (win)) #define GDK_DRAWABLE_XDISPLAY(win) (gdk_x11_drawable_get_xdisplay (win)) #define GDK_DRAWABLE_XID(win) (gdk_x11_drawable_get_xid (win)) diff --git a/gdk/x11/gdkxid.c b/gdk/x11/gdkxid.c index b4b46fe05f..c53ee38355 100644 --- a/gdk/x11/gdkxid.c +++ b/gdk/x11/gdkxid.c @@ -77,14 +77,16 @@ _gdk_xid_table_remove (GdkDisplay *display, g_hash_table_remove (display_x11->xid_ht, &xid); } -/** +/** * gdk_xid_table_lookup_for_display: * @display: the #GdkDisplay. * @xid: an X id. * * Returns the GDK object associated with the given X id. * - * Returns: a GDK object associated with the given X id. + * Return value: the associated Gdk object, which may be a #GdkPixmap, + * a #GdkWindow or a #GdkFont or %NULL if no object is associated + * with the X id. * * Since: 2.2 */ @@ -109,12 +111,14 @@ gdk_xid_table_lookup_for_display (GdkDisplay *display, /** * gdk_xid_table_lookup: * @xid: an X id. - * - * Returns the Gdk object associated with the given X id. - * + * + * Returns the Gdk object associated with the given X id for the default + * display. + * * Return value: the associated Gdk object, which may be a #GdkPixmap, - * a #GdkWindow or a #GdkFont. - **/ + * a #GdkWindow or a #GdkFont or %NULL if no object is associated + * with the X id. + */ gpointer gdk_xid_table_lookup (XID xid) { diff --git a/gtk/Makefile.am b/gtk/Makefile.am index 6d7a03865d..62d5352eea 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -197,6 +197,7 @@ gtk_public_h_sources = \ gtkdrawingarea.h \ gtkeditable.h \ gtkentry.h \ + gtkentrybuffer.h \ gtkentrycompletion.h \ gtkenums.h \ gtkeventbox.h \ @@ -357,6 +358,7 @@ gtk_private_h_sources = \ gtkdndcursors.h \ gtkentryprivate.h \ gtkbuilderprivate.h \ + gtkcustompaperunixdialog.h\ gtkfilechooserdefault.h \ gtkfilechooserembed.h \ gtkfilechooserentry.h \ @@ -369,6 +371,7 @@ gtk_private_h_sources = \ gtkintl.h \ gtkkeyhash.h \ gtkmnemonichash.h \ + gtkmountoperationprivate.h \ gtkpathbar.h \ gtkplugprivate.h \ gtkprintoperation-private.h\ @@ -446,6 +449,7 @@ gtk_base_c_sources = \ gtkdrawingarea.c \ gtkeditable.c \ gtkentry.c \ + gtkentrybuffer.c \ gtkentrycompletion.c \ gtkeventbox.c \ gtkexpander.c \ @@ -659,6 +663,7 @@ gtk_c_sources = $(gtk_base_c_sources) gtk_all_c_sources = $(gtk_base_c_sources) gtk_os_unix_c_sources = \ + gtkcustompaperunixdialog.c \ gtkpagesetupunixdialog.c \ gtkprinter.c \ gtkprinteroption.c \ @@ -697,19 +702,23 @@ gtk_use_x11_c_sources = \ gtkplug-x11.c \ gtksocket-x11.c \ gtkxembed.c \ - gtktrayicon-x11.c + gtktrayicon-x11.c \ + gtkmountoperation-x11.c gtk_use_win32_c_sources = \ gtkplug-win32.c \ gtksocket-win32.c \ gtkwin32embed.c \ - gtkwin32embedwidget.c + gtkwin32embedwidget.c \ + gtkmountoperation-stub.c gtk_use_quartz_c_sources = \ gtksearchenginequartz.c \ gtkplug-stub.c \ - gtksocket-stub.c + gtksocket-stub.c \ + gtkmountoperation-stub.c gtk_use_stub_c_sources = \ gtkplug-stub.c \ - gtksocket-stub.c + gtksocket-stub.c \ + gtkmountoperation-stub.c gtk_all_c_sources += $(gtk_use_x11_c_sources) $(gtk_use_win32_c_sources) $(gtk_use_quartz_c_sources) $(gtk_use_stub_c_sources) if USE_X11 gtk_private_h_sources += gtkxembed.h gtktrayicon.h xembed.h diff --git a/gtk/gtk.h b/gtk/gtk.h index b91a6badf5..211c2d253a 100644 --- a/gtk/gtk.h +++ b/gtk/gtk.h @@ -78,6 +78,7 @@ #include #include #include +#include #include #include #include diff --git a/gtk/gtk.symbols b/gtk/gtk.symbols index 0449189a70..841780b847 100644 --- a/gtk/gtk.symbols +++ b/gtk/gtk.symbols @@ -624,11 +624,19 @@ gtk_cell_renderer_activate #ifndef GTK_DISABLE_DEPRECATED gtk_cell_renderer_editing_canceled #endif +gtk_cell_renderer_get_alignment gtk_cell_renderer_get_fixed_size +gtk_cell_renderer_get_padding +gtk_cell_renderer_get_sensitive gtk_cell_renderer_get_size gtk_cell_renderer_get_type G_GNUC_CONST +gtk_cell_renderer_get_visible gtk_cell_renderer_render +gtk_cell_renderer_set_alignment gtk_cell_renderer_set_fixed_size +gtk_cell_renderer_set_padding +gtk_cell_renderer_set_sensitive +gtk_cell_renderer_set_visible gtk_cell_renderer_start_editing gtk_cell_renderer_stop_editing #endif @@ -679,10 +687,12 @@ gtk_cell_renderer_text_set_fixed_height_from_font #if IN_HEADER(__GTK_CELL_RENDERER_TOGGLE_H__) #if IN_FILE(__GTK_CELL_RENDERER_TOGGLE_C__) +gtk_cell_renderer_toggle_get_activatable gtk_cell_renderer_toggle_get_active gtk_cell_renderer_toggle_get_radio gtk_cell_renderer_toggle_get_type G_GNUC_CONST gtk_cell_renderer_toggle_new +gtk_cell_renderer_toggle_set_activatable gtk_cell_renderer_toggle_set_active gtk_cell_renderer_toggle_set_radio #endif @@ -1322,6 +1332,7 @@ gtk_editable_set_position #if IN_FILE(__GTK_ENTRY_C__) gtk_entry_get_activates_default gtk_entry_get_alignment +gtk_entry_get_buffer gtk_entry_get_completion gtk_entry_get_current_icon_drag_source gtk_entry_get_cursor_hadjustment @@ -1351,9 +1362,11 @@ gtk_entry_get_visibility gtk_entry_get_width_chars gtk_entry_layout_index_to_text_index gtk_entry_new +gtk_entry_new_with_buffer gtk_entry_progress_pulse gtk_entry_set_activates_default gtk_entry_set_alignment +gtk_entry_set_buffer gtk_entry_set_completion gtk_entry_set_cursor_hadjustment gtk_entry_set_has_frame @@ -1419,6 +1432,23 @@ gtk_entry_completion_set_text_column #endif #endif +#if IN_HEADER(__GTK_ENTRY_BUFFER_H__) +#if IN_FILE(__GTK_ENTRY_BUFFER_C__) +gtk_entry_buffer_get_type G_GNUC_CONST +gtk_entry_buffer_new +gtk_entry_buffer_get_bytes +gtk_entry_buffer_get_length +gtk_entry_buffer_get_text +gtk_entry_buffer_set_text +gtk_entry_buffer_set_max_length +gtk_entry_buffer_get_max_length +gtk_entry_buffer_insert_text +gtk_entry_buffer_delete_text +gtk_entry_buffer_emit_inserted_text +gtk_entry_buffer_emit_deleted_text +#endif +#endif + #if IN_HEADER(__GTK_EVENT_BOX_H__) #if IN_FILE(__GTK_EVENT_BOX_C__) gtk_event_box_get_above_child @@ -1501,6 +1531,8 @@ gtk_file_chooser_get_select_multiple gtk_file_chooser_get_show_hidden gtk_file_chooser_set_do_overwrite_confirmation gtk_file_chooser_get_do_overwrite_confirmation +gtk_file_chooser_set_create_folders +gtk_file_chooser_get_create_folders gtk_file_chooser_get_type G_GNUC_CONST gtk_file_chooser_get_uri gtk_file_chooser_get_uris @@ -1956,6 +1988,7 @@ gtk_icon_theme_set_search_path_utf8 gtk_icon_view_get_column_spacing gtk_icon_view_get_columns gtk_icon_view_get_cursor +gtk_icon_view_get_item_padding gtk_icon_view_get_item_width gtk_icon_view_get_margin gtk_icon_view_get_markup_column @@ -1983,6 +2016,7 @@ gtk_icon_view_select_path gtk_icon_view_set_column_spacing gtk_icon_view_set_columns gtk_icon_view_set_cursor +gtk_icon_view_set_item_padding gtk_icon_view_set_item_width gtk_icon_view_set_margin gtk_icon_view_set_markup_column @@ -2215,6 +2249,8 @@ gtk_label_set_use_markup gtk_label_set_use_underline gtk_label_set_width_chars gtk_label_get_current_uri +gtk_label_set_track_visited_links +gtk_label_get_track_visited_links #endif #endif @@ -2816,6 +2852,14 @@ gtk_paper_size_get_default #endif #endif +#if IN_HEADER(__GTK_CUSTOM_PAPER_UNIX_DIALOG_H__) +#if IN_FILE(__GTK_CUSTOM_PAPER_UNIX_DIALOG_C__) +#ifdef G_OS_UNIX +gtk_custom_paper_unix_dialog_get_type G_GNUC_CONST +#endif +#endif +#endif + #if IN_HEADER(__GTK_PRINT_BACKEND_H__) #if IN_FILE(__GTK_PRINT_BACKEND_C__) #ifdef G_OS_UNIX @@ -2913,6 +2957,8 @@ gtk_printer_option_clear_has_conflict gtk_printer_option_set_boolean gtk_printer_option_allocate_choices gtk_printer_option_choices_from_array +gtk_printer_option_set_activates_default +gtk_printer_option_get_activates_default #endif #endif #endif @@ -2974,6 +3020,7 @@ gtk_print_operation_set_allow_async gtk_print_operation_set_default_page_setup gtk_print_operation_get_default_page_setup gtk_print_operation_set_print_settings +gtk_print_operation_get_n_pages_to_print gtk_print_operation_get_print_settings gtk_print_operation_set_job_name gtk_print_operation_set_n_pages @@ -2996,6 +3043,8 @@ gtk_print_operation_set_support_selection gtk_print_operation_get_support_selection gtk_print_operation_set_has_selection gtk_print_operation_get_has_selection +gtk_print_operation_set_embed_page_setup +gtk_print_operation_get_embed_page_setup #endif #endif @@ -3125,6 +3174,9 @@ gtk_print_unix_dialog_set_support_selection gtk_print_unix_dialog_get_support_selection gtk_print_unix_dialog_set_has_selection gtk_print_unix_dialog_get_has_selection +gtk_print_unix_dialog_set_embed_page_setup +gtk_print_unix_dialog_get_embed_page_setup +gtk_print_unix_dialog_get_page_setup_set #endif #endif #endif @@ -3242,6 +3294,7 @@ gtk_radio_tool_button_set_group #if IN_FILE(__GTK_RANGE_C__) gtk_range_get_adjustment gtk_range_get_fill_level +gtk_range_get_flippable gtk_range_get_inverted gtk_range_get_lower_stepper_sensitivity gtk_range_get_restrict_to_fill_level @@ -3252,6 +3305,7 @@ gtk_range_get_upper_stepper_sensitivity gtk_range_get_value gtk_range_set_adjustment gtk_range_set_fill_level +gtk_range_set_flippable gtk_range_set_increments gtk_range_set_inverted gtk_range_set_lower_stepper_sensitivity @@ -4911,7 +4965,9 @@ gtk_widget_error_bell gtk_widget_event gtk_widget_freeze_child_notify gtk_widget_get_accessible +gtk_widget_get_allocation gtk_widget_get_ancestor +gtk_widget_get_app_paintable gtk_widget_get_child_requisition gtk_widget_get_child_visible gtk_widget_get_clipboard @@ -4923,6 +4979,7 @@ gtk_widget_get_default_style gtk_widget_get_default_visual gtk_widget_get_direction gtk_widget_get_display +gtk_widget_get_double_buffered gtk_widget_get_events gtk_widget_get_extension_events gtk_widget_get_has_tooltip @@ -4933,20 +4990,27 @@ gtk_widget_get_pango_context gtk_widget_get_parent gtk_widget_get_parent_window gtk_widget_get_pointer +gtk_widget_get_receives_default gtk_widget_get_root_window gtk_widget_get_screen +gtk_widget_get_sensitive gtk_widget_get_settings gtk_widget_get_size_request gtk_widget_get_snapshot +gtk_widget_get_state gtk_widget_get_style gtk_widget_get_tooltip_markup gtk_widget_get_tooltip_text gtk_widget_get_tooltip_window gtk_widget_get_toplevel gtk_widget_get_type G_GNUC_CONST +gtk_widget_get_visible gtk_widget_get_visual gtk_widget_grab_default gtk_widget_grab_focus +gtk_widget_has_default +gtk_widget_has_focus +gtk_widget_has_grab gtk_widget_has_screen gtk_widget_hide gtk_widget_hide_all @@ -4954,6 +5018,9 @@ gtk_widget_hide_on_delete gtk_widget_intersect gtk_widget_is_ancestor gtk_widget_is_focus +gtk_widget_is_sensitive +gtk_widget_is_toplevel +gtk_widget_is_drawable gtk_widget_keynav_failed gtk_widget_list_accel_closures gtk_widget_list_mnemonic_labels @@ -4996,6 +5063,7 @@ gtk_widget_reset_rc_styles gtk_widget_reset_shapes gtk_widget_send_expose gtk_widget_set_accel_path +gtk_widget_set_allocation gtk_widget_set_app_paintable gtk_widget_set_child_visible gtk_widget_set_colormap @@ -5011,6 +5079,7 @@ gtk_widget_set_name gtk_widget_set_no_show_all gtk_widget_set_parent gtk_widget_set_parent_window +gtk_widget_set_receives_default gtk_widget_set_redraw_on_allocate gtk_widget_set_scroll_adjustments gtk_widget_set_sensitive @@ -5020,6 +5089,8 @@ gtk_widget_set_style gtk_widget_set_tooltip_markup gtk_widget_set_tooltip_text gtk_widget_set_tooltip_window +gtk_widget_set_visible +gtk_widget_set_window gtk_widget_shape_combine_mask gtk_widget_input_shape_combine_mask gtk_widget_show @@ -5037,6 +5108,12 @@ gtk_widget_unmap gtk_widget_unparent gtk_widget_unrealize gtk_widget_get_window +gtk_widget_set_has_window +gtk_widget_get_has_window +gtk_widget_set_can_default +gtk_widget_get_can_default +gtk_widget_set_can_focus +gtk_widget_get_can_focus #endif #endif diff --git a/gtk/gtkassistant.c b/gtk/gtkassistant.c index b7ed75641d..a2e2f7ae3a 100644 --- a/gtk/gtkassistant.c +++ b/gtk/gtkassistant.c @@ -483,6 +483,7 @@ set_assistant_buttons_state (GtkAssistant *assistant) case GTK_ASSISTANT_PAGE_INTRO: gtk_widget_set_sensitive (assistant->cancel, TRUE); gtk_widget_set_sensitive (assistant->forward, priv->current_page->complete); + gtk_widget_grab_default (assistant->forward); gtk_widget_show (assistant->cancel); gtk_widget_show (assistant->forward); gtk_widget_hide (assistant->back); @@ -494,6 +495,7 @@ set_assistant_buttons_state (GtkAssistant *assistant) gtk_widget_set_sensitive (assistant->cancel, TRUE); gtk_widget_set_sensitive (assistant->back, TRUE); gtk_widget_set_sensitive (assistant->apply, priv->current_page->complete); + gtk_widget_grab_default (assistant->apply); gtk_widget_show (assistant->cancel); gtk_widget_show (assistant->back); gtk_widget_show (assistant->apply); @@ -505,6 +507,7 @@ set_assistant_buttons_state (GtkAssistant *assistant) gtk_widget_set_sensitive (assistant->cancel, TRUE); gtk_widget_set_sensitive (assistant->back, TRUE); gtk_widget_set_sensitive (assistant->forward, priv->current_page->complete); + gtk_widget_grab_default (assistant->forward); gtk_widget_show (assistant->cancel); gtk_widget_show (assistant->back); gtk_widget_show (assistant->forward); @@ -514,6 +517,7 @@ set_assistant_buttons_state (GtkAssistant *assistant) break; case GTK_ASSISTANT_PAGE_SUMMARY: gtk_widget_set_sensitive (assistant->close, TRUE); + gtk_widget_grab_default (assistant->close); gtk_widget_show (assistant->close); gtk_widget_hide (assistant->cancel); gtk_widget_hide (assistant->back); @@ -525,6 +529,7 @@ set_assistant_buttons_state (GtkAssistant *assistant) gtk_widget_set_sensitive (assistant->cancel, priv->current_page->complete); gtk_widget_set_sensitive (assistant->back, priv->current_page->complete); gtk_widget_set_sensitive (assistant->forward, priv->current_page->complete); + gtk_widget_grab_default (assistant->forward); gtk_widget_show (assistant->cancel); gtk_widget_show (assistant->back); gtk_widget_show (assistant->forward); @@ -640,10 +645,10 @@ on_assistant_apply (GtkWidget *widget, { gboolean success; - success = compute_next_step (assistant); - g_signal_emit (assistant, signals [APPLY], 0); + success = compute_next_step (assistant); + /* if the assistant hasn't switched to another page, just emit * the CLOSE signal, it't the last page in the assistant flow */ @@ -752,6 +757,9 @@ gtk_assistant_init (GtkAssistant *assistant) assistant->back = gtk_button_new_from_stock (GTK_STOCK_GO_BACK); assistant->cancel = gtk_button_new_from_stock (GTK_STOCK_CANCEL); assistant->last = gtk_button_new_from_stock (GTK_STOCK_GOTO_LAST); + GTK_WIDGET_SET_FLAGS (assistant->close, GTK_CAN_DEFAULT); + GTK_WIDGET_SET_FLAGS (assistant->apply, GTK_CAN_DEFAULT); + GTK_WIDGET_SET_FLAGS (assistant->forward, GTK_CAN_DEFAULT); priv->size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); gtk_size_group_add_widget (priv->size_group, assistant->close); @@ -1222,6 +1230,7 @@ gtk_assistant_map (GtkWidget *widget) GtkAssistant *assistant = GTK_ASSISTANT (widget); GtkAssistantPrivate *priv = assistant->priv; GList *page_node; + GtkAssistantPage *page; GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED); @@ -1233,7 +1242,8 @@ gtk_assistant_map (GtkWidget *widget) gtk_widget_map (priv->sidebar_image); /* if there's no default page, pick the first one */ - if (!priv->current_page && priv->pages) + page = NULL; + if (!priv->current_page) { page_node = priv->pages; @@ -1241,22 +1251,13 @@ gtk_assistant_map (GtkWidget *widget) page_node = page_node->next; if (page_node) - priv->current_page = page_node->data; + page = page_node->data; } - if (priv->current_page && - GTK_WIDGET_VISIBLE (priv->current_page->page) && - !GTK_WIDGET_MAPPED (priv->current_page->page)) - { - set_assistant_buttons_state ((GtkAssistant *) widget); - set_assistant_header_image ((GtkAssistant*) widget); - set_assistant_sidebar_image ((GtkAssistant*) widget); - - g_signal_emit (widget, signals [PREPARE], 0, priv->current_page->page); - gtk_widget_set_child_visible (priv->current_page->page, TRUE); - gtk_widget_map (priv->current_page->page); - gtk_widget_map (priv->current_page->title); - } + if (page && + GTK_WIDGET_VISIBLE (page->page) && + !GTK_WIDGET_MAPPED (page->page)) + set_current_page (assistant, page); GTK_WIDGET_CLASS (gtk_assistant_parent_class)->map (widget); } diff --git a/gtk/gtkbbox.c b/gtk/gtkbbox.c index 6ff894b759..3690a6b62c 100644 --- a/gtk/gtkbbox.c +++ b/gtk/gtkbbox.c @@ -26,6 +26,8 @@ #include "config.h" #include "gtkbbox.h" +#include "gtkhbbox.h" +#include "gtkvbbox.h" #include "gtkorientable.h" #include "gtkprivate.h" #include "gtkintl.h" @@ -491,9 +493,9 @@ gtk_button_box_kludge_get_layout_default (GtkButtonBox *widget) orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (widget)); if (orientation == GTK_ORIENTATION_HORIZONTAL) - return gtk_hbutton_box_get_layout_default (); + return _gtk_hbutton_box_get_layout_default (); else - return gtk_vbutton_box_get_layout_default (); + return _gtk_vbutton_box_get_layout_default (); } static void diff --git a/gtk/gtkbuilderparser.c b/gtk/gtkbuilderparser.c index f6f12a5bf6..b4f6855136 100644 --- a/gtk/gtkbuilderparser.c +++ b/gtk/gtkbuilderparser.c @@ -380,7 +380,12 @@ parse_object (GMarkupParseContext *context, data->inside_requested_object = TRUE; } else - return; + { + g_free (object_class); + g_free (object_id); + g_free (constructor); + return; + } } object_info = g_slice_new0 (ObjectInfo); @@ -404,7 +409,8 @@ parse_object (GMarkupParseContext *context, return; } - g_hash_table_insert (data->object_ids, object_id, GINT_TO_POINTER (line)); + + g_hash_table_insert (data->object_ids, g_strdup (object_id), GINT_TO_POINTER (line)); } static void @@ -1128,7 +1134,8 @@ _gtk_builder_parser_parse_buffer (GtkBuilder *builder, data->builder = builder; data->filename = filename; data->domain = g_strdup (domain); - data->object_ids = g_hash_table_new (g_str_hash, g_str_equal); + data->object_ids = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify)g_free, NULL); data->requested_objects = NULL; if (requested_objs) diff --git a/gtk/gtkbutton.c b/gtk/gtkbutton.c index 43ec81853b..c5757ac822 100644 --- a/gtk/gtkbutton.c +++ b/gtk/gtkbutton.c @@ -934,15 +934,15 @@ gtk_button_construct_child (GtkButton *button) GtkWidget *image = NULL; gchar *label_text = NULL; gint image_spacing; - + if (!button->constructed) return; - + if (!button->label_text && !priv->image) return; - - gtk_widget_style_get (GTK_WIDGET (button), - "image-spacing", &image_spacing, + + gtk_widget_style_get (GTK_WIDGET (button), + "image-spacing", &image_spacing, NULL); if (priv->image && !priv->image_is_stock) @@ -951,7 +951,7 @@ gtk_button_construct_child (GtkButton *button) if (image->parent) gtk_container_remove (GTK_CONTAINER (image->parent), image); } - + priv->image = NULL; if (GTK_BIN (button)->child) @@ -973,7 +973,7 @@ gtk_button_construct_child (GtkButton *button) if (image) { priv->image = image; - g_object_set (priv->image, + g_object_set (priv->image, "visible", show_image (button), "no-show-all", TRUE, NULL); @@ -997,7 +997,7 @@ gtk_button_construct_child (GtkButton *button) if (label_text) { - if (button->use_underline) + if (button->use_underline || button->use_stock) { label = gtk_label_new_with_mnemonic (label_text); gtk_label_set_mnemonic_widget (GTK_LABEL (label), @@ -1012,7 +1012,7 @@ gtk_button_construct_child (GtkButton *button) else gtk_box_pack_end (GTK_BOX (box), label, FALSE, FALSE, 0); } - + gtk_container_add (GTK_CONTAINER (button), align); gtk_container_add (GTK_CONTAINER (align), box); gtk_widget_show_all (align); @@ -1021,18 +1021,18 @@ gtk_button_construct_child (GtkButton *button) return; } - - if (button->use_underline) + + if (button->use_underline || button->use_stock) { label = gtk_label_new_with_mnemonic (button->label_text); gtk_label_set_mnemonic_widget (GTK_LABEL (label), GTK_WIDGET (button)); } else label = gtk_label_new (button->label_text); - + if (priv->align_set) gtk_misc_set_alignment (GTK_MISC (label), priv->xalign, priv->yalign); - + gtk_widget_show (label); gtk_container_add (GTK_CONTAINER (button), label); } diff --git a/gtk/gtkcalendar.c b/gtk/gtkcalendar.c index 20b2d86c44..8bc6e63cfe 100644 --- a/gtk/gtkcalendar.c +++ b/gtk/gtkcalendar.c @@ -751,9 +751,10 @@ gtk_calendar_init (GtkCalendar *calendar) * Do *not* translate it to anything else, if it * it isn't calendar:YM or calendar:MY it will not work. * - * Note that this flipping is in top of the text direction flipping, - * so if you have a default text direction of RTL and YM, then - * the year will appear on the right. + * Note that the ordering described here is logical order, which is + * further influenced by BIDI ordering. Thus, if you have a default + * text direction of RTL and specify "calendar:YM", then the year + * will appear to the right of the month. */ year_before = _("calendar:MY"); if (strcmp (year_before, "calendar:YM") == 0) diff --git a/gtk/gtkcellrenderer.c b/gtk/gtkcellrenderer.c index c41a7f857b..e4af9a1303 100644 --- a/gtk/gtkcellrenderer.c +++ b/gtk/gtkcellrenderer.c @@ -684,7 +684,7 @@ gtk_cell_renderer_start_editing (GtkCellRenderer *cell, * @cell: A #GtkCellRenderer * @width: the width of the cell renderer, or -1 * @height: the height of the cell renderer, or -1 - * + * * Sets the renderer size to be explicit, independent of the properties set. **/ void @@ -718,9 +718,9 @@ gtk_cell_renderer_set_fixed_size (GtkCellRenderer *cell, /** * gtk_cell_renderer_get_fixed_size: * @cell: A #GtkCellRenderer - * @width: location to fill in with the fixed width of the widget, or %NULL - * @height: location to fill in with the fixed height of the widget, or %NULL - * + * @width: location to fill in with the fixed width of the cell, or %NULL + * @height: location to fill in with the fixed height of the cell, or %NULL + * * Fills in @width and @height with the appropriate size of @cell. **/ void @@ -731,9 +731,212 @@ gtk_cell_renderer_get_fixed_size (GtkCellRenderer *cell, g_return_if_fail (GTK_IS_CELL_RENDERER (cell)); if (width) - (* width) = cell->width; + *width = cell->width; if (height) - (* height) = cell->height; + *height = cell->height; +} + +/** + * gtk_cell_renderer_set_alignment: + * @cell: A #GtkCellRenderer + * @xalign: the x alignment of the cell renderer + * @yalign: the y alignment of the cell renderer + * + * Sets the renderer's alignment within its available space. + * + * Since: 2.18 + **/ +void +gtk_cell_renderer_set_alignment (GtkCellRenderer *cell, + gfloat xalign, + gfloat yalign) +{ + g_return_if_fail (GTK_IS_CELL_RENDERER (cell)); + g_return_if_fail (xalign >= 0.0 && xalign <= 1.0); + g_return_if_fail (yalign >= 0.0 && yalign <= 1.0); + + if ((xalign != cell->xalign) || (yalign != cell->yalign)) + { + g_object_freeze_notify (G_OBJECT (cell)); + + if (xalign != cell->xalign) + { + cell->xalign = xalign; + g_object_notify (G_OBJECT (cell), "xalign"); + } + + if (yalign != cell->yalign) + { + cell->yalign = yalign; + g_object_notify (G_OBJECT (cell), "yalign"); + } + + g_object_thaw_notify (G_OBJECT (cell)); + } +} + +/** + * gtk_cell_renderer_get_alignment: + * @cell: A #GtkCellRenderer + * @xalign: location to fill in with the x alignment of the cell, or %NULL + * @yalign: location to fill in with the y alignment of the cell, or %NULL + * + * Fills in @xalign and @yalign with the appropriate values of @cell. + * + * Since: 2.18 + **/ +void +gtk_cell_renderer_get_alignment (GtkCellRenderer *cell, + gfloat *xalign, + gfloat *yalign) +{ + g_return_if_fail (GTK_IS_CELL_RENDERER (cell)); + + if (xalign) + *xalign = cell->xalign; + if (yalign) + *yalign = cell->yalign; +} + +/** + * gtk_cell_renderer_set_padding: + * @cell: A #GtkCellRenderer + * @xpad: the x padding of the cell renderer + * @ypad: the y padding of the cell renderer + * + * Sets the renderer's padding. + * + * Since: 2.18 + **/ +void +gtk_cell_renderer_set_padding (GtkCellRenderer *cell, + gint xpad, + gint ypad) +{ + g_return_if_fail (GTK_IS_CELL_RENDERER (cell)); + g_return_if_fail (xpad >= 0 && xpad >= 0); + + if ((xpad != cell->xpad) || (ypad != cell->ypad)) + { + g_object_freeze_notify (G_OBJECT (cell)); + + if (xpad != cell->xpad) + { + cell->xpad = xpad; + g_object_notify (G_OBJECT (cell), "xpad"); + } + + if (ypad != cell->ypad) + { + cell->ypad = ypad; + g_object_notify (G_OBJECT (cell), "ypad"); + } + + g_object_thaw_notify (G_OBJECT (cell)); + } +} + +/** + * gtk_cell_renderer_get_padding: + * @cell: A #GtkCellRenderer + * @xpad: location to fill in with the x padding of the cell, or %NULL + * @ypad: location to fill in with the y padding of the cell, or %NULL + * + * Fills in @xpad and @ypad with the appropriate values of @cell. + * + * Since: 2.18 + **/ +void +gtk_cell_renderer_get_padding (GtkCellRenderer *cell, + gint *xpad, + gint *ypad) +{ + g_return_if_fail (GTK_IS_CELL_RENDERER (cell)); + + if (xpad) + *xpad = cell->xpad; + if (ypad) + *ypad = cell->ypad; +} + +/** + * gtk_cell_renderer_set_visible: + * @cell: A #GtkCellRenderer + * @visible: the visibility of the cell + * + * Sets the cell renderer's visibility. + * + * Since: 2.18 + **/ +void +gtk_cell_renderer_set_visible (GtkCellRenderer *cell, + gboolean visible) +{ + g_return_if_fail (GTK_IS_CELL_RENDERER (cell)); + + if (cell->visible != visible) + { + cell->visible = visible ? TRUE : FALSE; + g_object_notify (G_OBJECT (cell), "visible"); + } +} + +/** + * gtk_cell_renderer_get_visible: + * @cell: A #GtkCellRenderer + * + * Returns the cell renderer's visibility. + * + * Returns: %TRUE if the cell renderer is visible + * + * Since: 2.18 + */ +gboolean +gtk_cell_renderer_get_visible (GtkCellRenderer *cell) +{ + g_return_val_if_fail (GTK_IS_CELL_RENDERER (cell), FALSE); + + return cell->visible; +} + +/** + * gtk_cell_renderer_set_sensitive: + * @cell: A #GtkCellRenderer + * @sensitive: the sensitivity of the cell + * + * Sets the cell renderer's sensitivity. + * + * Since: 2.18 + **/ +void +gtk_cell_renderer_set_sensitive (GtkCellRenderer *cell, + gboolean sensitive) +{ + g_return_if_fail (GTK_IS_CELL_RENDERER (cell)); + + if (cell->sensitive != sensitive) + { + cell->sensitive = sensitive ? TRUE : FALSE; + g_object_notify (G_OBJECT (cell), "sensitive"); + } +} + +/** + * gtk_cell_renderer_get_sensitive: + * @cell: A #GtkCellRenderer + * + * Returns the cell renderer's sensitivity. + * + * Returns: %TRUE if the cell renderer is sensitive + * + * Since: 2.18 + */ +gboolean +gtk_cell_renderer_get_sensitive (GtkCellRenderer *cell) +{ + g_return_val_if_fail (GTK_IS_CELL_RENDERER (cell), FALSE); + + return cell->sensitive; } /** diff --git a/gtk/gtkcellrenderer.h b/gtk/gtkcellrenderer.h index 8b54292692..aece202ae9 100644 --- a/gtk/gtkcellrenderer.h +++ b/gtk/gtkcellrenderer.h @@ -152,6 +152,7 @@ GtkCellEditable *gtk_cell_renderer_start_editing (GtkCellRenderer *cell, const GdkRectangle *background_area, const GdkRectangle *cell_area, GtkCellRendererState flags); + void gtk_cell_renderer_set_fixed_size (GtkCellRenderer *cell, gint width, gint height); @@ -159,6 +160,28 @@ void gtk_cell_renderer_get_fixed_size (GtkCellRenderer *cell, gint *width, gint *height); +void gtk_cell_renderer_set_alignment (GtkCellRenderer *cell, + gfloat xalign, + gfloat yalign); +void gtk_cell_renderer_get_alignment (GtkCellRenderer *cell, + gfloat *xalign, + gfloat *yalign); + +void gtk_cell_renderer_set_padding (GtkCellRenderer *cell, + gint xpad, + gint ypad); +void gtk_cell_renderer_get_padding (GtkCellRenderer *cell, + gint *xpad, + gint *ypad); + +void gtk_cell_renderer_set_visible (GtkCellRenderer *cell, + gboolean visible); +gboolean gtk_cell_renderer_get_visible (GtkCellRenderer *cell); + +void gtk_cell_renderer_set_sensitive (GtkCellRenderer *cell, + gboolean sensitive); +gboolean gtk_cell_renderer_get_sensitive (GtkCellRenderer *cell); + /* For use by cell renderer implementations only */ #ifndef GTK_DISABLE_DEPRECATED void gtk_cell_renderer_editing_canceled (GtkCellRenderer *cell); diff --git a/gtk/gtkcellrendereraccel.c b/gtk/gtkcellrendereraccel.c index f3e229688b..dedbfdae64 100644 --- a/gtk/gtkcellrendereraccel.c +++ b/gtk/gtkcellrendereraccel.c @@ -24,6 +24,7 @@ #include "gtkcellrendereraccel.h" #include "gtklabel.h" #include "gtkeventbox.h" +#include "gtkmain.h" #include "gtkprivate.h" #include "gdk/gdkkeysyms.h" #include "gtkalias.h" @@ -470,6 +471,7 @@ grab_key_callback (GtkWidget *widget, edited = TRUE; out: + gtk_grab_remove (accel->grab_widget); gdk_display_keyboard_ungrab (display, event->time); gdk_display_pointer_ungrab (display, event->time); @@ -497,6 +499,7 @@ ungrab_stuff (GtkWidget *widget, { GdkDisplay *display = gtk_widget_get_display (widget); + gtk_grab_remove (accel->grab_widget); gdk_display_keyboard_ungrab (display, GDK_CURRENT_TIME); gdk_display_pointer_ungrab (display, GDK_CURRENT_TIME); @@ -606,6 +609,8 @@ gtk_cell_renderer_accel_start_editing (GtkCellRenderer *cell, gtk_widget_show_all (accel->edit_widget); + gtk_grab_add (accel->grab_widget); + g_signal_connect (G_OBJECT (accel->edit_widget), "unrealize", G_CALLBACK (ungrab_stuff), accel); diff --git a/gtk/gtkcellrendererspin.c b/gtk/gtkcellrendererspin.c index 92b66926ad..ebd08e275c 100644 --- a/gtk/gtkcellrendererspin.c +++ b/gtk/gtkcellrendererspin.c @@ -271,6 +271,21 @@ gtk_cell_renderer_spin_key_press_event (GtkWidget *widget, return FALSE; } +static gboolean +gtk_cell_renderer_spin_button_press_event (GtkWidget *widget, + GdkEventButton *event, + gpointer user_data) +{ + /* Block 2BUTTON and 3BUTTON here, so that they won't be eaten + * by tree view. + */ + if (event->type == GDK_2BUTTON_PRESS + || event->type == GDK_3BUTTON_PRESS) + return TRUE; + + return FALSE; +} + static GtkCellEditable * gtk_cell_renderer_spin_start_editing (GtkCellRenderer *cell, GdkEvent *event, @@ -296,6 +311,10 @@ gtk_cell_renderer_spin_start_editing (GtkCellRenderer *cell, spin = gtk_spin_button_new (priv->adjustment, priv->climb_rate, priv->digits); + g_signal_connect (spin, "button-press-event", + G_CALLBACK (gtk_cell_renderer_spin_button_press_event), + NULL); + if (cell_text->text) gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin), g_ascii_strtod (cell_text->text, NULL)); diff --git a/gtk/gtkcellrenderertoggle.c b/gtk/gtkcellrenderertoggle.c index 5cc826ca9b..d097bb0847 100644 --- a/gtk/gtkcellrenderertoggle.c +++ b/gtk/gtkcellrenderertoggle.c @@ -349,7 +349,7 @@ gtk_cell_renderer_toggle_render (GtkCellRenderer *cell, else shadow = celltoggle->active ? GTK_SHADOW_IN : GTK_SHADOW_OUT; - if (!cell->sensitive) + if (GTK_WIDGET_STATE (widget) == GTK_STATE_INSENSITIVE || !cell->sensitive) { state = GTK_STATE_INSENSITIVE; } @@ -482,5 +482,46 @@ gtk_cell_renderer_toggle_set_active (GtkCellRendererToggle *toggle, g_object_set (toggle, "active", setting ? TRUE : FALSE, NULL); } +/** + * gtk_cell_renderer_toggle_get_activatable: + * @toggle: a #GtkCellRendererToggle + * + * Returns whether the cell renderer is activatable. See + * gtk_cell_renderer_toggle_set_activatable(). + * + * Return value: %TRUE if the cell renderer is activatable. + * + * Since: 2.18 + **/ +gboolean +gtk_cell_renderer_toggle_get_activatable (GtkCellRendererToggle *toggle) +{ + g_return_val_if_fail (GTK_IS_CELL_RENDERER_TOGGLE (toggle), FALSE); + + return toggle->activatable; +} + +/** + * gtk_cell_renderer_toggle_set_activatable: + * @toggle: a #GtkCellRendererToggle. + * @setting: the value to set. + * + * Makes the cell renderer activatable. + * + * Since: 2.18 + **/ +void +gtk_cell_renderer_toggle_set_activatable (GtkCellRendererToggle *toggle, + gboolean setting) +{ + g_return_if_fail (GTK_IS_CELL_RENDERER_TOGGLE (toggle)); + + if (toggle->activatable != setting) + { + toggle->activatable = setting ? TRUE : FALSE; + g_object_notify (G_OBJECT (toggle), "activatable"); + } +} + #define __GTK_CELL_RENDERER_TOGGLE_C__ #include "gtkaliasdef.c" diff --git a/gtk/gtkcellrenderertoggle.h b/gtk/gtkcellrenderertoggle.h index c9b85a191e..cf6a3c2f3d 100644 --- a/gtk/gtkcellrenderertoggle.h +++ b/gtk/gtkcellrenderertoggle.h @@ -64,16 +64,20 @@ struct _GtkCellRendererToggleClass void (*_gtk_reserved4) (void); }; -GType gtk_cell_renderer_toggle_get_type (void) G_GNUC_CONST; -GtkCellRenderer *gtk_cell_renderer_toggle_new (void); +GType gtk_cell_renderer_toggle_get_type (void) G_GNUC_CONST; +GtkCellRenderer *gtk_cell_renderer_toggle_new (void); -gboolean gtk_cell_renderer_toggle_get_radio (GtkCellRendererToggle *toggle); -void gtk_cell_renderer_toggle_set_radio (GtkCellRendererToggle *toggle, - gboolean radio); +gboolean gtk_cell_renderer_toggle_get_radio (GtkCellRendererToggle *toggle); +void gtk_cell_renderer_toggle_set_radio (GtkCellRendererToggle *toggle, + gboolean radio); -gboolean gtk_cell_renderer_toggle_get_active (GtkCellRendererToggle *toggle); -void gtk_cell_renderer_toggle_set_active (GtkCellRendererToggle *toggle, - gboolean setting); +gboolean gtk_cell_renderer_toggle_get_active (GtkCellRendererToggle *toggle); +void gtk_cell_renderer_toggle_set_active (GtkCellRendererToggle *toggle, + gboolean setting); + +gboolean gtk_cell_renderer_toggle_get_activatable (GtkCellRendererToggle *toggle); +void gtk_cell_renderer_toggle_set_activatable (GtkCellRendererToggle *toggle, + gboolean setting); G_END_DECLS diff --git a/gtk/gtkcellview.c b/gtk/gtkcellview.c index 6add539de8..5f8fe39574 100644 --- a/gtk/gtkcellview.c +++ b/gtk/gtkcellview.c @@ -438,6 +438,8 @@ gtk_cell_view_expose (GtkWidget *widget, if (GTK_WIDGET_STATE (widget) == GTK_STATE_PRELIGHT) state = GTK_CELL_RENDERER_PRELIT; + else if (GTK_WIDGET_STATE (widget) == GTK_STATE_INSENSITIVE) + state = GTK_CELL_RENDERER_INSENSITIVE; else state = 0; @@ -1042,23 +1044,10 @@ gtk_cell_view_set_background_color (GtkCellView *cell_view, gtk_widget_queue_draw (GTK_WIDGET (cell_view)); } -/** - * gtk_cell_view_get_cell_renderers: - * @cell_view: a #GtkCellView - * - * Returns the cell renderers which have been added to @cell_view. - * - * Return value: a list of cell renderers. The list, but not the - * renderers has been newly allocated and should be freed with - * g_list_free() when no longer needed. - * - * Since: 2.6 - * - * Deprecated: 2.18: use gtk_cell_layout_get_cells() instead. - **/ -GList * -gtk_cell_view_get_cell_renderers (GtkCellView *cell_view) +static GList * +gtk_cell_view_cell_layout_get_cells (GtkCellLayout *layout) { + GtkCellView *cell_view = GTK_CELL_VIEW (layout); GList *retval = NULL, *list; g_return_val_if_fail (cell_view != NULL, NULL); @@ -1075,13 +1064,26 @@ gtk_cell_view_get_cell_renderers (GtkCellView *cell_view) return g_list_reverse (retval); } -static GList * -gtk_cell_view_cell_layout_get_cells (GtkCellLayout *layout) +/** + * gtk_cell_view_get_cell_renderers: + * @cell_view: a #GtkCellView + * + * Returns the cell renderers which have been added to @cell_view. + * + * Return value: a list of cell renderers. The list, but not the + * renderers has been newly allocated and should be freed with + * g_list_free() when no longer needed. + * + * Since: 2.6 + * + * Deprecated: 2.18: use gtk_cell_layout_get_cells() instead. + **/ +GList * +gtk_cell_view_get_cell_renderers (GtkCellView *cell_view) { - return gtk_cell_view_get_cell_renderers (GTK_CELL_VIEW (layout)); + return gtk_cell_view_cell_layout_get_cells (GTK_CELL_LAYOUT (cell_view)); } - static gboolean gtk_cell_view_buildable_custom_tag_start (GtkBuildable *buildable, GtkBuilder *builder, diff --git a/gtk/gtkclist.c b/gtk/gtkclist.c index 74302d1edb..f09d6b1371 100644 --- a/gtk/gtkclist.c +++ b/gtk/gtkclist.c @@ -5925,8 +5925,14 @@ draw_rows (GtkCList *clist, } if (!area) - gdk_window_clear_area (clist->clist_window, 0, - ROW_TOP_YPIXEL (clist, i), 0, 0); + { + int w, h, y; + gdk_drawable_get_size (GDK_DRAWABLE (clist->clist_window), &w, &h); + y = ROW_TOP_YPIXEL (clist, i); + gdk_window_clear_area (clist->clist_window, + 0, y, + w, h - y); + } } static void diff --git a/gtk/gtkcombobox.c b/gtk/gtkcombobox.c index 4e4349e7e2..c5e021f089 100644 --- a/gtk/gtkcombobox.c +++ b/gtk/gtkcombobox.c @@ -379,6 +379,8 @@ static gboolean gtk_combo_box_menu_button_press (GtkWidget *widget, gpointer user_data); static void gtk_combo_box_menu_item_activate (GtkWidget *item, gpointer user_data); + +static void gtk_combo_box_update_sensitivity (GtkComboBox *combo_box); static void gtk_combo_box_menu_row_inserted (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, @@ -1470,15 +1472,17 @@ gtk_combo_box_menu_position_below (GtkMenu *menu, /* FIXME: is using the size request here broken? */ child = GTK_BIN (combo_box)->child; - - gdk_window_get_origin (child->window, &sx, &sy); - + + sx = sy = 0; + if (GTK_WIDGET_NO_WINDOW (child)) { sx += child->allocation.x; sy += child->allocation.y; } + gdk_window_get_root_coords (child->window, sx, sy, &sx, &sy); + if (GTK_SHADOW_NONE != combo_box->priv->shadow_type) sx -= GTK_WIDGET (combo_box)->style->xthickness; @@ -1537,10 +1541,9 @@ gtk_combo_box_menu_position_over (GtkMenu *menu, menu_width = requisition.width; active = gtk_menu_get_active (GTK_MENU (combo_box->priv->popup_widget)); - gdk_window_get_origin (widget->window, &menu_xpos, &menu_ypos); - menu_xpos += widget->allocation.x; - menu_ypos += widget->allocation.y + widget->allocation.height / 2 - 2; + menu_xpos = widget->allocation.x; + menu_ypos = widget->allocation.y + widget->allocation.height / 2 - 2; if (active != NULL) { @@ -1568,6 +1571,9 @@ gtk_combo_box_menu_position_over (GtkMenu *menu, if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) menu_xpos = menu_xpos + widget->allocation.width - menu_width; + gdk_window_get_root_coords (widget->window, menu_xpos, menu_ypos, + &menu_xpos, &menu_ypos); + /* Clamp the position on screen */ screen_width = gdk_screen_get_width (gtk_widget_get_screen (widget)); @@ -1630,7 +1636,7 @@ gtk_combo_box_list_position (GtkComboBox *combo_box, see bug #340204 */ GtkWidget *sample = GTK_WIDGET (combo_box); - gdk_window_get_origin (sample->window, x, y); + *x = *y = 0; if (GTK_WIDGET_NO_WINDOW (sample)) { @@ -1638,6 +1644,8 @@ gtk_combo_box_list_position (GtkComboBox *combo_box, *y += sample->allocation.y; } + gdk_window_get_root_coords (sample->window, *x, *y, x, y); + *width = sample->allocation.width; hpolicy = vpolicy = GTK_POLICY_NEVER; @@ -2856,6 +2864,7 @@ gtk_combo_box_menu_setup (GtkComboBox *combo_box, gtk_combo_box_sync_cells (combo_box, GTK_CELL_LAYOUT (priv->column)); gtk_combo_box_update_title (combo_box); + gtk_combo_box_update_sensitivity (combo_box); } static void @@ -3209,6 +3218,11 @@ gtk_combo_box_update_sensitivity (GtkComboBox *combo_box) } gtk_widget_set_sensitive (combo_box->priv->button, sensitive); + + /* In list-mode, we also need to update sensitivity of the event box */ + if (GTK_IS_TREE_VIEW (combo_box->priv->tree_view) + && combo_box->priv->cell_view) + gtk_widget_set_sensitive (combo_box->priv->box, sensitive); } static void @@ -3749,6 +3763,8 @@ gtk_combo_box_list_setup (GtkComboBox *combo_box) combo_box); gtk_widget_show (priv->tree_view); + + gtk_combo_box_update_sensitivity (combo_box); } static void diff --git a/gtk/gtkcomboboxentry.c b/gtk/gtkcomboboxentry.c index 93ae5aea01..c63c08561b 100644 --- a/gtk/gtkcomboboxentry.c +++ b/gtk/gtkcomboboxentry.c @@ -368,9 +368,10 @@ void gtk_combo_box_entry_set_text_column (GtkComboBoxEntry *entry_box, gint text_column) { + GtkTreeModel *model = gtk_combo_box_get_model (GTK_COMBO_BOX (entry_box)); + g_return_if_fail (text_column >= 0); - g_return_if_fail (text_column < gtk_tree_model_get_n_columns (gtk_combo_box_get_model (GTK_COMBO_BOX (entry_box)))); - g_return_if_fail (entry_box->priv->text_column == -1); + g_return_if_fail (model == NULL || text_column < gtk_tree_model_get_n_columns (model)); entry_box->priv->text_column = text_column; diff --git a/gtk/gtkcustompaperunixdialog.c b/gtk/gtkcustompaperunixdialog.c new file mode 100644 index 0000000000..9006eaba23 --- /dev/null +++ b/gtk/gtkcustompaperunixdialog.c @@ -0,0 +1,1187 @@ +/* GtkCustomPaperUnixDialog + * Copyright (C) 2006 Alexander Larsson + * Copyright © 2006, 2007, 2008 Christian Persch + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + + +#include "config.h" +#include +#include + +#ifdef HAVE__NL_MEASUREMENT_MEASUREMENT +#include +#endif + +#include "gtkintl.h" +#include "gtkprivate.h" + +#include "gtkliststore.h" + +#include "gtktreeviewcolumn.h" +#include "gtklabel.h" +#include "gtkspinbutton.h" + +#include "gtkcustompaperunixdialog.h" +#include "gtkprintbackend.h" +#include "gtkprintutils.h" +#include "gtkprinter-private.h" +#include "gtkalias.h" + +#define CUSTOM_PAPER_FILENAME ".gtk-custom-papers" + + +typedef struct +{ + GtkUnit display_unit; + GtkWidget *spin_button; +} UnitWidget; + +struct GtkCustomPaperUnixDialogPrivate +{ + + GtkWidget *treeview; + GtkWidget *values_box; + GtkWidget *printer_combo; + GtkWidget *width_widget; + GtkWidget *height_widget; + GtkWidget *top_widget; + GtkWidget *bottom_widget; + GtkWidget *left_widget; + GtkWidget *right_widget; + + GtkTreeViewColumn *text_column; + + gulong printer_inserted_tag; + gulong printer_removed_tag; + + guint request_details_tag; + GtkPrinter *request_details_printer; + + guint non_user_change : 1; + + GtkListStore *custom_paper_list; + GtkListStore *printer_list; + + GList *print_backends; + + gchar *waiting_for_printer; +}; + +enum { + PRINTER_LIST_COL_NAME, + PRINTER_LIST_COL_PRINTER, + PRINTER_LIST_N_COLS +}; + +G_DEFINE_TYPE (GtkCustomPaperUnixDialog, gtk_custom_paper_unix_dialog, GTK_TYPE_DIALOG) + +#define GTK_CUSTOM_PAPER_UNIX_DIALOG_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_CUSTOM_PAPER_UNIX_DIALOG, GtkCustomPaperUnixDialogPrivate)) + +static void gtk_custom_paper_unix_dialog_finalize (GObject *object); +static void populate_dialog (GtkCustomPaperUnixDialog *dialog); +static void printer_added_cb (GtkPrintBackend *backend, + GtkPrinter *printer, + GtkCustomPaperUnixDialog *dialog); +static void printer_removed_cb (GtkPrintBackend *backend, + GtkPrinter *printer, + GtkCustomPaperUnixDialog *dialog); +static void printer_status_cb (GtkPrintBackend *backend, + GtkPrinter *printer, + GtkCustomPaperUnixDialog *dialog); + + + +GtkUnit +_gtk_print_get_default_user_units (void) +{ + /* Translate to the default units to use for presenting + * lengths to the user. Translate to default:inch if you + * want inches, otherwise translate to default:mm. + * Do *not* translate it to "predefinito:mm", if it + * it isn't default:mm or default:inch it will not work + */ + gchar *e = _("default:mm"); + +#ifdef HAVE__NL_MEASUREMENT_MEASUREMENT + gchar *imperial = NULL; + + imperial = nl_langinfo (_NL_MEASUREMENT_MEASUREMENT); + if (imperial && imperial[0] == 2 ) + return GTK_UNIT_INCH; /* imperial */ + if (imperial && imperial[0] == 1 ) + return GTK_UNIT_MM; /* metric */ +#endif + + if (strcmp (e, "default:inch")==0) + return GTK_UNIT_INCH; + else if (strcmp (e, "default:mm")) + g_warning ("Whoever translated default:mm did so wrongly.\n"); + return GTK_UNIT_MM; +} + +static char * +custom_paper_get_filename (void) +{ + gchar *filename; + + filename = g_build_filename (g_get_home_dir (), + CUSTOM_PAPER_FILENAME, NULL); + g_assert (filename != NULL); + return filename; +} + +GList * +_gtk_load_custom_papers (void) +{ + GKeyFile *keyfile; + gchar *filename; + gchar **groups; + gsize n_groups, i; + gboolean load_ok; + GList *result = NULL; + + filename = custom_paper_get_filename (); + + keyfile = g_key_file_new (); + load_ok = g_key_file_load_from_file (keyfile, filename, 0, NULL); + g_free (filename); + if (!load_ok) + { + g_key_file_free (keyfile); + return NULL; + } + + groups = g_key_file_get_groups (keyfile, &n_groups); + for (i = 0; i < n_groups; ++i) + { + GtkPageSetup *page_setup; + + page_setup = gtk_page_setup_new_from_key_file (keyfile, groups[i], NULL); + if (!page_setup) + continue; + + result = g_list_prepend (result, page_setup); + } + + g_strfreev (groups); + g_key_file_free (keyfile); + + return g_list_reverse (result); +} + +void +_gtk_print_load_custom_papers (GtkListStore *store) +{ + GtkTreeIter iter; + GList *papers, *p; + GtkPageSetup *page_setup; + + gtk_list_store_clear (store); + + papers = _gtk_load_custom_papers (); + for (p = papers; p; p = p->next) + { + page_setup = p->data; + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + 0, page_setup, + -1); + g_object_unref (page_setup); + } + + g_list_free (papers); +} + +void +_gtk_print_save_custom_papers (GtkListStore *store) +{ + GtkTreeModel *model = GTK_TREE_MODEL (store); + GtkTreeIter iter; + GKeyFile *keyfile; + gchar *filename, *data; + gsize len; + gint i = 0; + + keyfile = g_key_file_new (); + + if (gtk_tree_model_get_iter_first (model, &iter)) + { + do + { + GtkPageSetup *page_setup; + gchar group[32]; + + g_snprintf (group, sizeof (group), "Paper%u", i); + + gtk_tree_model_get (model, &iter, 0, &page_setup, -1); + + gtk_page_setup_to_key_file (page_setup, keyfile, group); + + ++i; + } while (gtk_tree_model_iter_next (model, &iter)); + } + + filename = custom_paper_get_filename (); + data = g_key_file_to_data (keyfile, &len, NULL); + g_file_set_contents (filename, data, len, NULL); + g_free (data); + g_free (filename); +} + +static void +gtk_custom_paper_unix_dialog_class_init (GtkCustomPaperUnixDialogClass *class) +{ + GObjectClass *object_class; + GtkWidgetClass *widget_class; + + object_class = (GObjectClass *) class; + widget_class = (GtkWidgetClass *) class; + + object_class->finalize = gtk_custom_paper_unix_dialog_finalize; + + g_type_class_add_private (class, sizeof (GtkCustomPaperUnixDialogPrivate)); +} + +static void +custom_paper_dialog_response_cb (GtkDialog *dialog, + gint response, + gpointer user_data) +{ + GtkCustomPaperUnixDialogPrivate *priv = GTK_CUSTOM_PAPER_UNIX_DIALOG (dialog)->priv; + + _gtk_print_save_custom_papers (priv->custom_paper_list); +} + +static void +gtk_custom_paper_unix_dialog_init (GtkCustomPaperUnixDialog *dialog) +{ + GtkCustomPaperUnixDialogPrivate *priv; + GtkTreeIter iter; + + priv = dialog->priv = GTK_CUSTOM_PAPER_UNIX_DIALOG_GET_PRIVATE (dialog); + + priv->print_backends = NULL; + + priv->request_details_printer = NULL; + priv->request_details_tag = 0; + + priv->printer_list = gtk_list_store_new (PRINTER_LIST_N_COLS, + G_TYPE_STRING, + G_TYPE_OBJECT); + + gtk_list_store_append (priv->printer_list, &iter); + + priv->custom_paper_list = gtk_list_store_new (1, G_TYPE_OBJECT); + _gtk_print_load_custom_papers (priv->custom_paper_list); + + populate_dialog (dialog); + + gtk_dialog_add_buttons (GTK_DIALOG (dialog), + GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, + NULL); + + gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CLOSE); + + g_signal_connect (dialog, "response", G_CALLBACK (custom_paper_dialog_response_cb), NULL); +} + +static void +gtk_custom_paper_unix_dialog_finalize (GObject *object) +{ + GtkCustomPaperUnixDialog *dialog = GTK_CUSTOM_PAPER_UNIX_DIALOG (object); + GtkCustomPaperUnixDialogPrivate *priv = dialog->priv; + GtkPrintBackend *backend; + GList *node; + + if (priv->printer_list) + { + g_signal_handler_disconnect (priv->printer_list, priv->printer_inserted_tag); + g_signal_handler_disconnect (priv->printer_list, priv->printer_removed_tag); + g_object_unref (priv->printer_list); + priv->printer_list = NULL; + } + + if (priv->request_details_tag) + { + g_signal_handler_disconnect (priv->request_details_printer, + priv->request_details_tag); + g_object_unref (priv->request_details_printer); + priv->request_details_printer = NULL; + priv->request_details_tag = 0; + } + + if (priv->custom_paper_list) + { + g_object_unref (priv->custom_paper_list); + priv->custom_paper_list = NULL; + } + + g_free (priv->waiting_for_printer); + priv->waiting_for_printer = NULL; + + for (node = priv->print_backends; node != NULL; node = node->next) + { + backend = GTK_PRINT_BACKEND (node->data); + + g_signal_handlers_disconnect_by_func (backend, printer_added_cb, dialog); + g_signal_handlers_disconnect_by_func (backend, printer_removed_cb, dialog); + g_signal_handlers_disconnect_by_func (backend, printer_status_cb, dialog); + + gtk_print_backend_destroy (backend); + g_object_unref (backend); + } + + g_list_free (priv->print_backends); + priv->print_backends = NULL; + + G_OBJECT_CLASS (gtk_custom_paper_unix_dialog_parent_class)->finalize (object); +} + +/** + * gtk_custom_paper_unix_dialog_new: + * @title: the title of the dialog, or %NULL + * @parent: transient parent of the dialog, or %NULL + * + * Creates a new custom paper dialog. + * + * Returns: the new #GtkCustomPaperUnixDialog + * + * Since: 2.18 + */ +GtkWidget * +_gtk_custom_paper_unix_dialog_new (GtkWindow *parent, + const gchar *title) +{ + GtkWidget *result; + + if (title == NULL) + title = _("Manage Custom Sizes"); + + result = g_object_new (GTK_TYPE_CUSTOM_PAPER_UNIX_DIALOG, + "title", title, + "transient-for", parent, + "modal", parent != NULL, + "destroy-with-parent", TRUE, + NULL); + + return result; +} + +static void +printer_added_cb (GtkPrintBackend *backend, + GtkPrinter *printer, + GtkCustomPaperUnixDialog *dialog) +{ + GtkCustomPaperUnixDialogPrivate *priv = dialog->priv; + GtkTreeIter iter; + gchar *str; + + if (gtk_printer_is_virtual (printer)) + return; + + str = g_strdup_printf ("%s", + gtk_printer_get_name (printer)); + + gtk_list_store_append (priv->printer_list, &iter); + gtk_list_store_set (priv->printer_list, &iter, + PRINTER_LIST_COL_NAME, str, + PRINTER_LIST_COL_PRINTER, printer, + -1); + + g_object_set_data_full (G_OBJECT (printer), + "gtk-print-tree-iter", + gtk_tree_iter_copy (&iter), + (GDestroyNotify) gtk_tree_iter_free); + + g_free (str); + + if (priv->waiting_for_printer != NULL && + strcmp (priv->waiting_for_printer, + gtk_printer_get_name (printer)) == 0) + { + gtk_combo_box_set_active_iter (GTK_COMBO_BOX (priv->printer_combo), + &iter); + priv->waiting_for_printer = NULL; + } +} + +static void +printer_removed_cb (GtkPrintBackend *backend, + GtkPrinter *printer, + GtkCustomPaperUnixDialog *dialog) +{ + GtkCustomPaperUnixDialogPrivate *priv = dialog->priv; + GtkTreeIter *iter; + + iter = g_object_get_data (G_OBJECT (printer), "gtk-print-tree-iter"); + gtk_list_store_remove (GTK_LIST_STORE (priv->printer_list), iter); +} + + +static void +printer_status_cb (GtkPrintBackend *backend, + GtkPrinter *printer, + GtkCustomPaperUnixDialog *dialog) +{ + GtkCustomPaperUnixDialogPrivate *priv = dialog->priv; + GtkTreeIter *iter; + gchar *str; + + iter = g_object_get_data (G_OBJECT (printer), "gtk-print-tree-iter"); + + str = g_strdup_printf ("%s", + gtk_printer_get_name (printer)); + gtk_list_store_set (priv->printer_list, iter, + PRINTER_LIST_COL_NAME, str, + -1); + g_free (str); +} + +static void +printer_list_initialize (GtkCustomPaperUnixDialog *dialog, + GtkPrintBackend *print_backend) +{ + GList *list, *node; + + g_return_if_fail (print_backend != NULL); + + g_signal_connect_object (print_backend, + "printer-added", + (GCallback) printer_added_cb, + G_OBJECT (dialog), 0); + + g_signal_connect_object (print_backend, + "printer-removed", + (GCallback) printer_removed_cb, + G_OBJECT (dialog), 0); + + g_signal_connect_object (print_backend, + "printer-status-changed", + (GCallback) printer_status_cb, + G_OBJECT (dialog), 0); + + list = gtk_print_backend_get_printer_list (print_backend); + + node = list; + while (node != NULL) + { + printer_added_cb (print_backend, node->data, dialog); + node = node->next; + } + + g_list_free (list); +} + +static void +load_print_backends (GtkCustomPaperUnixDialog *dialog) +{ + GtkCustomPaperUnixDialogPrivate *priv = dialog->priv; + GList *node; + + if (g_module_supported ()) + priv->print_backends = gtk_print_backend_load_modules (); + + for (node = priv->print_backends; node != NULL; node = node->next) + printer_list_initialize (dialog, GTK_PRINT_BACKEND (node->data)); +} + +static void unit_widget_changed (GtkCustomPaperUnixDialog *dialog); + +static GtkWidget * +new_unit_widget (GtkCustomPaperUnixDialog *dialog, + GtkUnit unit, + GtkWidget *mnemonic_label) +{ + GtkWidget *hbox, *button, *label; + UnitWidget *data; + + data = g_new0 (UnitWidget, 1); + data->display_unit = unit; + + hbox = gtk_hbox_new (FALSE, 6); + + button = gtk_spin_button_new_with_range (0.0, 9999.0, 1); + if (unit == GTK_UNIT_INCH) + gtk_spin_button_set_digits (GTK_SPIN_BUTTON (button), 2); + else + gtk_spin_button_set_digits (GTK_SPIN_BUTTON (button), 1); + + gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0); + gtk_widget_show (button); + + data->spin_button = button; + + g_signal_connect_swapped (button, "value-changed", + G_CALLBACK (unit_widget_changed), dialog); + + if (unit == GTK_UNIT_INCH) + label = gtk_label_new (_("inch")); + else + label = gtk_label_new (_("mm")); + + gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); + gtk_widget_show (label); + gtk_label_set_mnemonic_widget (GTK_LABEL (mnemonic_label), button); + + g_object_set_data_full (G_OBJECT (hbox), "unit-data", data, g_free); + + return hbox; +} + +static double +unit_widget_get (GtkWidget *unit_widget) +{ + UnitWidget *data = g_object_get_data (G_OBJECT (unit_widget), "unit-data"); + return _gtk_print_convert_to_mm (gtk_spin_button_get_value (GTK_SPIN_BUTTON (data->spin_button)), + data->display_unit); +} + +static void +unit_widget_set (GtkWidget *unit_widget, + gdouble value) +{ + UnitWidget *data; + + data = g_object_get_data (G_OBJECT (unit_widget), "unit-data"); + gtk_spin_button_set_value (GTK_SPIN_BUTTON (data->spin_button), + _gtk_print_convert_from_mm (value, data->display_unit)); +} + +static void +custom_paper_printer_data_func (GtkCellLayout *cell_layout, + GtkCellRenderer *cell, + GtkTreeModel *tree_model, + GtkTreeIter *iter, + gpointer data) +{ + GtkPrinter *printer; + + gtk_tree_model_get (tree_model, iter, + PRINTER_LIST_COL_PRINTER, &printer, -1); + + if (printer) + g_object_set (cell, "text", gtk_printer_get_name (printer), NULL); + else + g_object_set (cell, "text", _("Margins from Printer..."), NULL); + + if (printer) + g_object_unref (printer); +} + +static void +update_combo_sensitivity_from_printers (GtkCustomPaperUnixDialog *dialog) +{ + GtkCustomPaperUnixDialogPrivate *priv = dialog->priv; + GtkTreeIter iter; + gboolean sensitive; + GtkTreeSelection *selection; + GtkTreeModel *model; + + sensitive = FALSE; + model = GTK_TREE_MODEL (priv->printer_list); + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview)); + if (gtk_tree_model_get_iter_first (model, &iter) && + gtk_tree_model_iter_next (model, &iter) && + gtk_tree_selection_get_selected (selection, NULL, &iter)) + sensitive = TRUE; + + gtk_widget_set_sensitive (priv->printer_combo, sensitive); +} + +static void +update_custom_widgets_from_list (GtkCustomPaperUnixDialog *dialog) +{ + GtkCustomPaperUnixDialogPrivate *priv = dialog->priv; + GtkTreeSelection *selection; + GtkTreeModel *model; + GtkTreeIter iter; + GtkPageSetup *page_setup; + + model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview)); + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview)); + + priv->non_user_change = TRUE; + if (gtk_tree_selection_get_selected (selection, NULL, &iter)) + { + gtk_tree_model_get (model, &iter, 0, &page_setup, -1); + + unit_widget_set (priv->width_widget, + gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_MM)); + unit_widget_set (priv->height_widget, + gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_MM)); + unit_widget_set (priv->top_widget, + gtk_page_setup_get_top_margin (page_setup, GTK_UNIT_MM)); + unit_widget_set (priv->bottom_widget, + gtk_page_setup_get_bottom_margin (page_setup, GTK_UNIT_MM)); + unit_widget_set (priv->left_widget, + gtk_page_setup_get_left_margin (page_setup, GTK_UNIT_MM)); + unit_widget_set (priv->right_widget, + gtk_page_setup_get_right_margin (page_setup, GTK_UNIT_MM)); + + gtk_widget_set_sensitive (priv->values_box, TRUE); + } + else + { + gtk_widget_set_sensitive (priv->values_box, FALSE); + } + + if (priv->printer_list) + update_combo_sensitivity_from_printers (dialog); + priv->non_user_change = FALSE; +} + +static void +selected_custom_paper_changed (GtkTreeSelection *selection, + GtkCustomPaperUnixDialog *dialog) +{ + update_custom_widgets_from_list (dialog); +} + +static void +unit_widget_changed (GtkCustomPaperUnixDialog *dialog) +{ + GtkCustomPaperUnixDialogPrivate *priv = dialog->priv; + gdouble w, h, top, bottom, left, right; + GtkTreeSelection *selection; + GtkTreeIter iter; + GtkPageSetup *page_setup; + GtkPaperSize *paper_size; + + if (priv->non_user_change) + return; + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview)); + + if (gtk_tree_selection_get_selected (selection, NULL, &iter)) + { + gtk_tree_model_get (GTK_TREE_MODEL (priv->custom_paper_list), &iter, 0, &page_setup, -1); + + w = unit_widget_get (priv->width_widget); + h = unit_widget_get (priv->height_widget); + + paper_size = gtk_page_setup_get_paper_size (page_setup); + gtk_paper_size_set_size (paper_size, w, h, GTK_UNIT_MM); + + top = unit_widget_get (priv->top_widget); + bottom = unit_widget_get (priv->bottom_widget); + left = unit_widget_get (priv->left_widget); + right = unit_widget_get (priv->right_widget); + + gtk_page_setup_set_top_margin (page_setup, top, GTK_UNIT_MM); + gtk_page_setup_set_bottom_margin (page_setup, bottom, GTK_UNIT_MM); + gtk_page_setup_set_left_margin (page_setup, left, GTK_UNIT_MM); + gtk_page_setup_set_right_margin (page_setup, right, GTK_UNIT_MM); + + g_object_unref (page_setup); + } +} + +static gboolean +custom_paper_name_used (GtkCustomPaperUnixDialog *dialog, + const gchar *name) +{ + GtkCustomPaperUnixDialogPrivate *priv = dialog->priv; + GtkTreeModel *model; + GtkTreeIter iter; + GtkPageSetup *page_setup; + GtkPaperSize *paper_size; + + model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview)); + + if (gtk_tree_model_get_iter_first (model, &iter)) + { + do + { + gtk_tree_model_get (model, &iter, 0, &page_setup, -1); + paper_size = gtk_page_setup_get_paper_size (page_setup); + if (strcmp (name, + gtk_paper_size_get_name (paper_size)) == 0) + { + g_object_unref (page_setup); + return TRUE; + } + g_object_unref (page_setup); + } while (gtk_tree_model_iter_next (model, &iter)); + } + + return FALSE; +} + +static void +add_custom_paper (GtkCustomPaperUnixDialog *dialog) +{ + GtkCustomPaperUnixDialogPrivate *priv = dialog->priv; + GtkListStore *store; + GtkPageSetup *page_setup; + GtkPaperSize *paper_size; + GtkTreeSelection *selection; + GtkTreePath *path; + GtkTreeIter iter; + gchar *name; + gint i; + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview)); + store = priv->custom_paper_list; + + i = 1; + name = NULL; + do + { + g_free (name); + name = g_strdup_printf (_("Custom Size %d"), i); + i++; + } while (custom_paper_name_used (dialog, name)); + + page_setup = gtk_page_setup_new (); + paper_size = gtk_paper_size_new_custom (name, name, + gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_MM), + gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_MM), + GTK_UNIT_MM); + gtk_page_setup_set_paper_size (page_setup, paper_size); + gtk_paper_size_free (paper_size); + + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, 0, page_setup, -1); + g_object_unref (page_setup); + + gtk_tree_selection_select_iter (selection, &iter); + path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter); + gtk_widget_grab_focus (priv->treeview); + gtk_tree_view_set_cursor (GTK_TREE_VIEW (priv->treeview), path, + priv->text_column, TRUE); + gtk_tree_path_free (path); + g_free (name); +} + +static void +remove_custom_paper (GtkCustomPaperUnixDialog *dialog) +{ + GtkCustomPaperUnixDialogPrivate *priv = dialog->priv; + GtkTreeSelection *selection; + GtkTreeIter iter; + GtkListStore *store; + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview)); + store = priv->custom_paper_list; + + if (gtk_tree_selection_get_selected (selection, NULL, &iter)) + { + GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter); + gtk_list_store_remove (store, &iter); + + if (gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path)) + gtk_tree_selection_select_iter (selection, &iter); + else if (gtk_tree_path_prev (path) && gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path)) + gtk_tree_selection_select_iter (selection, &iter); + + gtk_tree_path_free (path); + } +} + +static void +set_margins_from_printer (GtkCustomPaperUnixDialog *dialog, + GtkPrinter *printer) +{ + GtkCustomPaperUnixDialogPrivate *priv = dialog->priv; + gdouble top, bottom, left, right; + + top = bottom = left = right = 0; + _gtk_printer_get_hard_margins (printer, &top, &bottom, &left, &right); + + priv->non_user_change = TRUE; + unit_widget_set (priv->top_widget, _gtk_print_convert_to_mm (top, GTK_UNIT_POINTS)); + unit_widget_set (priv->bottom_widget, _gtk_print_convert_to_mm (bottom, GTK_UNIT_POINTS)); + unit_widget_set (priv->left_widget, _gtk_print_convert_to_mm (left, GTK_UNIT_POINTS)); + unit_widget_set (priv->right_widget, _gtk_print_convert_to_mm (right, GTK_UNIT_POINTS)); + priv->non_user_change = FALSE; + + /* Only send one change */ + unit_widget_changed (dialog); +} + +static void +get_margins_finished_callback (GtkPrinter *printer, + gboolean success, + GtkCustomPaperUnixDialog *dialog) +{ + GtkCustomPaperUnixDialogPrivate *priv = dialog->priv; + + g_signal_handler_disconnect (priv->request_details_printer, + priv->request_details_tag); + g_object_unref (priv->request_details_printer); + priv->request_details_tag = 0; + priv->request_details_printer = NULL; + + if (success) + set_margins_from_printer (dialog, printer); + + gtk_combo_box_set_active (GTK_COMBO_BOX (priv->printer_combo), 0); +} + +static void +margins_from_printer_changed (GtkCustomPaperUnixDialog *dialog) +{ + GtkCustomPaperUnixDialogPrivate *priv = dialog->priv; + GtkTreeIter iter; + GtkComboBox *combo; + GtkPrinter *printer; + + combo = GTK_COMBO_BOX (priv->printer_combo); + + if (priv->request_details_tag) + { + g_signal_handler_disconnect (priv->request_details_printer, + priv->request_details_tag); + g_object_unref (priv->request_details_printer); + priv->request_details_printer = NULL; + priv->request_details_tag = 0; + } + + if (gtk_combo_box_get_active_iter (combo, &iter)) + { + gtk_tree_model_get (gtk_combo_box_get_model (combo), &iter, + PRINTER_LIST_COL_PRINTER, &printer, -1); + + if (printer) + { + if (gtk_printer_has_details (printer)) + { + set_margins_from_printer (dialog, printer); + gtk_combo_box_set_active (combo, 0); + } + else + { + priv->request_details_printer = g_object_ref (printer); + priv->request_details_tag = + g_signal_connect (printer, "details-acquired", + G_CALLBACK (get_margins_finished_callback), dialog); + gtk_printer_request_details (printer); + } + + g_object_unref (printer); + } + } +} + +static void +custom_size_name_edited (GtkCellRenderer *cell, + gchar *path_string, + gchar *new_text, + GtkCustomPaperUnixDialog *dialog) +{ + GtkCustomPaperUnixDialogPrivate *priv = dialog->priv; + GtkTreePath *path; + GtkTreeIter iter; + GtkListStore *store; + GtkPageSetup *page_setup; + GtkPaperSize *paper_size; + + store = priv->custom_paper_list; + path = gtk_tree_path_new_from_string (path_string); + gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path); + gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, 0, &page_setup, -1); + gtk_tree_path_free (path); + + paper_size = gtk_paper_size_new_custom (new_text, new_text, + gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_MM), + gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_MM), + GTK_UNIT_MM); + gtk_page_setup_set_paper_size (page_setup, paper_size); + gtk_paper_size_free (paper_size); + + g_object_unref (page_setup); +} + +static void +custom_name_func (GtkTreeViewColumn *tree_column, + GtkCellRenderer *cell, + GtkTreeModel *tree_model, + GtkTreeIter *iter, + gpointer data) +{ + GtkPageSetup *page_setup; + GtkPaperSize *paper_size; + + gtk_tree_model_get (tree_model, iter, 0, &page_setup, -1); + if (page_setup) + { + paper_size = gtk_page_setup_get_paper_size (page_setup); + g_object_set (cell, "text", gtk_paper_size_get_display_name (paper_size), NULL); + g_object_unref (page_setup); + } +} + +static GtkWidget * +wrap_in_frame (const gchar *label, + GtkWidget *child) +{ + GtkWidget *frame, *alignment, *label_widget; + gchar *bold_text; + + label_widget = gtk_label_new (NULL); + gtk_misc_set_alignment (GTK_MISC (label_widget), 0.0, 0.5); + gtk_widget_show (label_widget); + + bold_text = g_markup_printf_escaped ("%s", label); + gtk_label_set_markup (GTK_LABEL (label_widget), bold_text); + g_free (bold_text); + + frame = gtk_vbox_new (FALSE, 6); + gtk_box_pack_start (GTK_BOX (frame), label_widget, FALSE, FALSE, 0); + + alignment = gtk_alignment_new (0.0, 0.0, 1.0, 1.0); + gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), + 0, 0, 12, 0); + gtk_box_pack_start (GTK_BOX (frame), alignment, FALSE, FALSE, 0); + + gtk_container_add (GTK_CONTAINER (alignment), child); + + gtk_widget_show (frame); + gtk_widget_show (alignment); + + return frame; +} + +static void +populate_dialog (GtkCustomPaperUnixDialog *dialog) +{ + GtkCustomPaperUnixDialogPrivate *priv = dialog->priv; + GtkWidget *image, *table, *label, *widget, *frame, *combo; + GtkWidget *hbox, *vbox, *treeview, *scrolled, *button_box, *button; + GtkCellRenderer *cell; + GtkTreeViewColumn *column; + GtkTreeIter iter; + GtkTreeSelection *selection; + GtkUnit user_units; + + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); + gtk_container_set_border_width (GTK_CONTAINER (dialog), 5); + gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 2); /* 2 * 5 + 2 = 12 */ + gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area), 5); + gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->action_area), 6); + + hbox = gtk_hbox_new (FALSE, 18); + gtk_container_set_border_width (GTK_CONTAINER (hbox), 5); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox, TRUE, TRUE, 0); + gtk_widget_show (hbox); + + vbox = gtk_vbox_new (FALSE, 6); + gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0); + gtk_widget_show (vbox); + + scrolled = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled), + GTK_SHADOW_IN); + gtk_box_pack_start (GTK_BOX (vbox), scrolled, TRUE, TRUE, 0); + gtk_widget_show (scrolled); + + treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (priv->custom_paper_list)); + priv->treeview = treeview; + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE); + gtk_widget_set_size_request (treeview, 140, -1); + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); + gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE); + g_signal_connect (selection, "changed", G_CALLBACK (selected_custom_paper_changed), dialog); + + cell = gtk_cell_renderer_text_new (); + g_object_set (cell, "editable", TRUE, NULL); + g_signal_connect (cell, "edited", + G_CALLBACK (custom_size_name_edited), dialog); + priv->text_column = column = + gtk_tree_view_column_new_with_attributes ("paper", cell, + NULL); + gtk_tree_view_column_set_cell_data_func (column, cell, custom_name_func, NULL, NULL); + + gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); + + gtk_container_add (GTK_CONTAINER (scrolled), treeview); + gtk_widget_show (treeview); + + button_box = gtk_hbox_new (FALSE, 6); + gtk_box_pack_start (GTK_BOX (vbox), button_box, FALSE, FALSE, 0); + gtk_widget_show (button_box); + + button = gtk_button_new (); + image = gtk_image_new_from_stock (GTK_STOCK_ADD, GTK_ICON_SIZE_BUTTON); + gtk_widget_show (image); + gtk_container_add (GTK_CONTAINER (button), image); + gtk_box_pack_start (GTK_BOX (button_box), button, FALSE, FALSE, 0); + gtk_widget_show (button); + + g_signal_connect_swapped (button, "clicked", G_CALLBACK (add_custom_paper), dialog); + + button = gtk_button_new (); + image = gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_BUTTON); + gtk_widget_show (image); + gtk_container_add (GTK_CONTAINER (button), image); + gtk_box_pack_start (GTK_BOX (button_box), button, FALSE, FALSE, 0); + gtk_widget_show (button); + + g_signal_connect_swapped (button, "clicked", G_CALLBACK (remove_custom_paper), dialog); + + user_units = _gtk_print_get_default_user_units (); + + vbox = gtk_vbox_new (FALSE, 18); + priv->values_box = vbox; + gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0); + gtk_widget_show (vbox); + + table = gtk_table_new (2, 2, FALSE); + + gtk_table_set_row_spacings (GTK_TABLE (table), 6); + gtk_table_set_col_spacings (GTK_TABLE (table), 12); + + label = gtk_label_new_with_mnemonic (_("_Width:")); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_widget_show (label); + gtk_table_attach (GTK_TABLE (table), label, + 0, 1, 0, 1, GTK_FILL, 0, 0, 0); + + widget = new_unit_widget (dialog, user_units, label); + priv->width_widget = widget; + gtk_table_attach (GTK_TABLE (table), widget, + 1, 2, 0, 1, GTK_FILL, 0, 0, 0); + gtk_widget_show (widget); + + label = gtk_label_new_with_mnemonic (_("_Height:")); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_widget_show (label); + gtk_table_attach (GTK_TABLE (table), label, + 0, 1, 1, 2, GTK_FILL, 0, 0, 0); + + widget = new_unit_widget (dialog, user_units, label); + priv->height_widget = widget; + gtk_table_attach (GTK_TABLE (table), widget, + 1, 2, 1, 2, GTK_FILL, 0, 0, 0); + gtk_widget_show (widget); + + frame = wrap_in_frame (_("Paper Size"), table); + gtk_widget_show (table); + gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); + gtk_widget_show (frame); + + table = gtk_table_new (5, 2, FALSE); + gtk_table_set_row_spacings (GTK_TABLE (table), 6); + gtk_table_set_col_spacings (GTK_TABLE (table), 12); + + label = gtk_label_new_with_mnemonic (_("_Top:")); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_table_attach (GTK_TABLE (table), label, + 0, 1, 0, 1, GTK_FILL, 0, 0, 0); + gtk_widget_show (label); + + widget = new_unit_widget (dialog, user_units, label); + priv->top_widget = widget; + gtk_table_attach (GTK_TABLE (table), widget, + 1, 2, 0, 1, GTK_FILL, 0, 0, 0); + gtk_widget_show (widget); + + label = gtk_label_new_with_mnemonic (_("_Bottom:")); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_table_attach (GTK_TABLE (table), label, + 0, 1 , 1, 2, GTK_FILL, 0, 0, 0); + gtk_widget_show (label); + + widget = new_unit_widget (dialog, user_units, label); + priv->bottom_widget = widget; + gtk_table_attach (GTK_TABLE (table), widget, + 1, 2, 1, 2, GTK_FILL, 0, 0, 0); + gtk_widget_show (widget); + + label = gtk_label_new_with_mnemonic (_("_Left:")); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_table_attach (GTK_TABLE (table), label, + 0, 1, 2, 3, GTK_FILL, 0, 0, 0); + gtk_widget_show (label); + + widget = new_unit_widget (dialog, user_units, label); + priv->left_widget = widget; + gtk_table_attach (GTK_TABLE (table), widget, + 1, 2, 2, 3, GTK_FILL, 0, 0, 0); + gtk_widget_show (widget); + + label = gtk_label_new_with_mnemonic (_("_Right:")); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_table_attach (GTK_TABLE (table), label, + 0, 1, 3, 4, GTK_FILL, 0, 0, 0); + gtk_widget_show (label); + + widget = new_unit_widget (dialog, user_units, label); + priv->right_widget = widget; + gtk_table_attach (GTK_TABLE (table), widget, + 1, 2, 3, 4, GTK_FILL, 0, 0, 0); + gtk_widget_show (widget); + + hbox = gtk_hbox_new (FALSE, 0); + gtk_table_attach (GTK_TABLE (table), hbox, + 0, 2, 4, 5, GTK_FILL | GTK_EXPAND, 0, 0, 0); + gtk_widget_show (hbox); + + combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (priv->printer_list)); + priv->printer_combo = combo; + + priv->printer_inserted_tag = + g_signal_connect_swapped (priv->printer_list, "row-inserted", + G_CALLBACK (update_combo_sensitivity_from_printers), dialog); + priv->printer_removed_tag = + g_signal_connect_swapped (priv->printer_list, "row-deleted", + G_CALLBACK (update_combo_sensitivity_from_printers), dialog); + update_combo_sensitivity_from_printers (dialog); + + cell = gtk_cell_renderer_text_new (); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), cell, TRUE); + gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combo), cell, + custom_paper_printer_data_func, + NULL, NULL); + + gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0); + gtk_box_pack_start (GTK_BOX (hbox), combo, FALSE, FALSE, 0); + gtk_widget_show (combo); + + g_signal_connect_swapped (combo, "changed", + G_CALLBACK (margins_from_printer_changed), dialog); + + frame = wrap_in_frame (_("Paper Margins"), table); + gtk_widget_show (table); + gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); + gtk_widget_show (frame); + + update_custom_widgets_from_list (dialog); + + /* If no custom sizes, add one */ + if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->custom_paper_list), + &iter)) + { + /* Need to realize treeview so we can start the rename */ + gtk_widget_realize (treeview); + add_custom_paper (dialog); + } + + gtk_window_present (GTK_WINDOW (dialog)); + + load_print_backends (dialog); +} + + +#define __GTK_CUSTOM_PAPER_UNIX_DIALOG_C__ +#include "gtkaliasdef.c" diff --git a/gtk/gtkcustompaperunixdialog.h b/gtk/gtkcustompaperunixdialog.h new file mode 100644 index 0000000000..0ff3af165d --- /dev/null +++ b/gtk/gtkcustompaperunixdialog.h @@ -0,0 +1,70 @@ +/* GtkCustomPaperUnixDialog + * Copyright (C) 2006 Alexander Larsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GTK_CUSTOM_PAPER_UNIX_DIALOG_H__ +#define __GTK_CUSTOM_PAPER_UNIX_DIALOG_H__ + +#include + +G_BEGIN_DECLS + +#define GTK_TYPE_CUSTOM_PAPER_UNIX_DIALOG (gtk_custom_paper_unix_dialog_get_type ()) +#define GTK_CUSTOM_PAPER_UNIX_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_CUSTOM_PAPER_UNIX_DIALOG, GtkCustomPaperUnixDialog)) +#define GTK_CUSTOM_PAPER_UNIX_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_CUSTOM_PAPER_UNIX_DIALOG, GtkCustomPaperUnixDialogClass)) +#define GTK_IS_CUSTOM_PAPER_UNIX_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_CUSTOM_PAPER_UNIX_DIALOG)) +#define GTK_IS_CUSTOM_PAPER_UNIX_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_CUSTOM_PAPER_UNIX_DIALOG)) +#define GTK_CUSTOM_PAPER_UNIX_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CUSTOM_PAPER_UNIX_DIALOG, GtkCustomPaperUnixDialogClass)) + + +typedef struct _GtkCustomPaperUnixDialog GtkCustomPaperUnixDialog; +typedef struct _GtkCustomPaperUnixDialogClass GtkCustomPaperUnixDialogClass; +typedef struct GtkCustomPaperUnixDialogPrivate GtkCustomPaperUnixDialogPrivate; + +struct _GtkCustomPaperUnixDialog +{ + GtkDialog parent_instance; + + GtkCustomPaperUnixDialogPrivate *GSEAL (priv); +}; + +struct _GtkCustomPaperUnixDialogClass +{ + GtkDialogClass parent_class; + + /* Padding for future expansion */ + void (*_gtk_reserved1) (void); + void (*_gtk_reserved2) (void); + void (*_gtk_reserved3) (void); + void (*_gtk_reserved4) (void); + void (*_gtk_reserved5) (void); + void (*_gtk_reserved6) (void); + void (*_gtk_reserved7) (void); +}; + +GType gtk_custom_paper_unix_dialog_get_type (void) G_GNUC_CONST; +GtkWidget * _gtk_custom_paper_unix_dialog_new (GtkWindow *parent, + const gchar *title); +GtkUnit _gtk_print_get_default_user_units (void); +void _gtk_print_load_custom_papers (GtkListStore *store); +void _gtk_print_save_custom_papers (GtkListStore *store); + + +G_END_DECLS + +#endif /* __GTK_CUSTOM_PAPER_UNIX_DIALOG_H__ */ diff --git a/gtk/gtkdnd-quartz.c b/gtk/gtkdnd-quartz.c index fd66836360..275ebba0bd 100644 --- a/gtk/gtkdnd-quartz.c +++ b/gtk/gtkdnd-quartz.c @@ -63,6 +63,11 @@ static GtkDragDestInfo *gtk_drag_get_dest_info (GdkDragContext *context, gboolean create); static void gtk_drag_source_site_destroy (gpointer data); +static GtkDragSourceInfo *gtk_drag_get_source_info (GdkDragContext *context, + gboolean create); + +extern GdkDragContext *gdk_quartz_drag_source_context (); /* gdk/quartz/gdkdnd-quartz.c */ + struct _GtkDragSourceSite { GdkModifierType start_button_mask; @@ -89,13 +94,16 @@ struct _GtkDragSourceSite struct _GtkDragSourceInfo { + GtkWidget *source_widget; GtkWidget *widget; GtkTargetList *target_list; /* Targets for drag data */ GdkDragAction possible_actions; /* Actions allowed by source */ GdkDragContext *context; /* drag context */ - + NSEvent *nsevent; /* what started it */ gint hot_x, hot_y; /* Hot spot for drag */ GdkPixbuf *icon_pixbuf; + gboolean success; + gboolean delete; }; struct _GtkDragDestSite @@ -233,19 +241,24 @@ gtk_drag_get_data (GtkWidget *widget, } } - -GtkWidget * -gtk_drag_get_source_widget (GdkDragContext *context) -{ - return NULL; -} - void gtk_drag_finish (GdkDragContext *context, gboolean success, gboolean del, guint32 time) { + GtkDragSourceInfo *info; + GdkDragContext* source_context = gdk_quartz_drag_source_context (); + + if (source_context) + { + info = gtk_drag_get_source_info (source_context, FALSE); + if (info) + { + info->success = success; + info->delete = del; + } + } } static void @@ -307,6 +320,22 @@ gtk_drag_clear_source_info (GdkDragContext *context) g_object_set_qdata (G_OBJECT (context), dest_info_quark, NULL); } +GtkWidget * +gtk_drag_get_source_widget (GdkDragContext *context) +{ + GtkDragSourceInfo *info; + GdkDragContext* real_source_context = gdk_quartz_drag_source_context(); + + if (!real_source_context) + return NULL; + + info = gtk_drag_get_source_info (real_source_context, FALSE); + if (!info) + return NULL; + + return info->source_widget; +} + /************************************************************* * gtk_drag_highlight_expose: * Callback for expose_event for highlighted widgets. @@ -1031,6 +1060,45 @@ gtk_drag_dest_find_target (GtkWidget *widget, return GDK_NONE; } +static gboolean +gtk_drag_begin_idle (gpointer arg) +{ + GdkDragContext* context = (GdkDragContext*) arg; + GtkDragSourceInfo* info = gtk_drag_get_source_info (context, FALSE); + NSWindow *nswindow; + NSPasteboard *pasteboard; + GtkDragSourceOwner *owner; + NSPoint point; + + g_assert (info != NULL); + + pasteboard = [NSPasteboard pasteboardWithName:NSDragPboard]; + owner = [[GtkDragSourceOwner alloc] initWithInfo:info]; + + [pasteboard declareTypes:_gtk_quartz_target_list_to_pasteboard_types (info->target_list) owner:owner]; + + if ((nswindow = get_toplevel_nswindow (info->source_widget)) == NULL) + return FALSE; + + /* Ref the context. It's unreffed when the drag has been aborted */ + g_object_ref (info->context); + + /* FIXME: If the event isn't a mouse event, use the global cursor position instead */ + point = [info->nsevent locationInWindow]; + + [nswindow dragImage:_gtk_quartz_create_image_from_pixbuf (info->icon_pixbuf) + at:point + offset:NSMakeSize(0, 0) + event:info->nsevent + pasteboard:pasteboard + source:nswindow + slideBack:YES]; + + [info->nsevent release]; + + return FALSE; +} + static GdkDragContext * gtk_drag_begin_internal (GtkWidget *widget, GtkDragSourceSite *site, @@ -1042,16 +1110,13 @@ gtk_drag_begin_internal (GtkWidget *widget, GtkDragSourceInfo *info; GdkDragContext *context; NSWindow *nswindow; - NSPasteboard *pasteboard; - GtkDragSourceOwner *owner; - NSEvent *nsevent; - NSPoint point; context = gdk_drag_begin (NULL, NULL); context->is_source = TRUE; info = gtk_drag_get_source_info (context, TRUE); + info->source_widget = g_object_ref (widget); info->widget = g_object_ref (widget); info->target_list = target_list; gtk_target_list_ref (target_list); @@ -1086,13 +1151,13 @@ gtk_drag_begin_internal (GtkWidget *widget, GdkPixbuf *pixbuf; pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, 1, 1); - gdk_pixbuf_fill (pixbuf, 0xffffff); - - gtk_drag_set_icon_pixbuf (context, - pixbuf, + gdk_pixbuf_fill (pixbuf, 0xffffff); + + gtk_drag_set_icon_pixbuf (context, + pixbuf, 0, 0); - g_object_unref (pixbuf); + g_object_unref (pixbuf); } break; case GTK_IMAGE_PIXBUF: @@ -1117,31 +1182,17 @@ gtk_drag_begin_internal (GtkWidget *widget, } } - gdk_pointer_ungrab (0); - - pasteboard = [NSPasteboard pasteboardWithName:NSDragPboard]; - owner = [[GtkDragSourceOwner alloc] initWithInfo:info]; - - [pasteboard declareTypes:_gtk_quartz_target_list_to_pasteboard_types (target_list) owner:owner]; - - /* Ref the context. It's unreffed when the drag has been aborted */ - g_object_ref (info->context); - nswindow = get_toplevel_nswindow (widget); + info->nsevent = [nswindow currentEvent]; + [info->nsevent retain]; - /* FIXME: If the event isn't a mouse event, use the global cursor position instead */ - nsevent = [nswindow currentEvent]; - point = [nsevent locationInWindow]; + /* drag will begin in an idle handler to avoid nested run loops */ - [nswindow dragImage:_gtk_quartz_create_image_from_pixbuf (info->icon_pixbuf) - at:point - offset:NSMakeSize(0, 0) - event:nsevent - pasteboard:pasteboard - source:nswindow - slideBack:YES]; + g_idle_add_full (G_PRIORITY_HIGH_IDLE, gtk_drag_begin_idle, context, NULL); - return info->context; + gdk_pointer_ungrab (0); + + return context; } GdkDragContext * @@ -1773,6 +1824,9 @@ gtk_drag_source_info_destroy (GtkDragSourceInfo *info) g_signal_emit_by_name (info->widget, "drag-end", info->context); + if (info->source_widget) + g_object_unref (info->source_widget); + if (info->widget) g_object_unref (info->widget); @@ -1794,6 +1848,10 @@ drag_drop_finished_idle_cb (gpointer data) static void gtk_drag_drop_finished (GtkDragSourceInfo *info) { + if (info->success && info->delete) + g_signal_emit_by_name (info->source_widget, "drag-data-delete", + info->context); + /* Workaround for the fact that the NS API blocks until the drag is * over. This way the context is still valid when returning from * drag_begin, even if it will still be quite useless. See bug #501588. diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c index 5473143f72..8145905226 100644 --- a/gtk/gtkentry.c +++ b/gtk/gtkentry.c @@ -40,6 +40,7 @@ #include "gtkclipboard.h" #include "gtkdnd.h" #include "gtkentry.h" +#include "gtkentrybuffer.h" #include "gtkimagemenuitem.h" #include "gtkimcontextsimple.h" #include "gtkimmulticontext.h" @@ -73,12 +74,6 @@ #define COMPLETION_TIMEOUT 300 #define PASSWORD_HINT_MAX 8 -/* Initial size of buffer, in bytes */ -#define MIN_SIZE 16 - -/* Maximum size of text buffer, in bytes */ -#define MAX_SIZE G_MAXUSHORT - #define MAX_ICONS 2 #define IS_VALID_ICON_POSITION(pos) \ @@ -117,6 +112,8 @@ typedef struct struct _GtkEntryPrivate { + GtkEntryBuffer* buffer; + gfloat xalign; gint insert_pos; guint blink_time; /* time in msec the cursor has blinked since last user event */ @@ -148,10 +145,8 @@ typedef struct _GtkEntryPasswordHint GtkEntryPasswordHint; struct _GtkEntryPasswordHint { - gchar password_hint[PASSWORD_HINT_MAX]; - guint password_hint_timeout_id; - gint password_hint_length; - gint password_hint_position; + gint position; /* Position (in text) of the last password hint */ + guint source_id; /* Timeout source id */ }; typedef struct _GtkEntryCapslockFeedback GtkEntryCapslockFeedback; @@ -181,6 +176,7 @@ enum { enum { PROP_0, + PROP_BUFFER, PROP_CURSOR_POSITION, PROP_SELECTION_BOUND, PROP_EDITABLE, @@ -230,6 +226,13 @@ typedef enum { CURSOR_DND } CursorType; +typedef enum +{ + DISPLAY_NORMAL, /* The entry text is being shown */ + DISPLAY_INVISIBLE, /* In invisible mode, text replaced by (eg) bullets */ + DISPLAY_BLANK /* In invisible mode, nothing shown at all */ +} DisplayMode; + /* GObject, GtkObject methods */ static void gtk_entry_editable_init (GtkEditableClass *iface); @@ -439,9 +442,6 @@ static gint gtk_entry_move_backward_word (GtkEntry *entry, static void gtk_entry_delete_whitespace (GtkEntry *entry); static void gtk_entry_select_word (GtkEntry *entry); static void gtk_entry_select_line (GtkEntry *entry); -static char * gtk_entry_get_public_chars (GtkEntry *entry, - gint start, - gint end); static void gtk_entry_paste (GtkEntry *entry, GdkAtom selection); static void gtk_entry_update_primary_selection (GtkEntry *entry); @@ -501,6 +501,29 @@ static void end_change (GtkEntry *entry); static void emit_changed (GtkEntry *entry); +static void buffer_inserted_text (GtkEntryBuffer *buffer, + guint position, + const gchar *chars, + guint n_chars, + GtkEntry *entry); +static void buffer_deleted_text (GtkEntryBuffer *buffer, + guint position, + guint n_chars, + GtkEntry *entry); +static void buffer_notify_text (GtkEntryBuffer *buffer, + GParamSpec *spec, + GtkEntry *entry); +static void buffer_notify_length (GtkEntryBuffer *buffer, + GParamSpec *spec, + GtkEntry *entry); +static void buffer_notify_max_length (GtkEntryBuffer *buffer, + GParamSpec *spec, + GtkEntry *entry); +static void buffer_connect_signals (GtkEntry *entry); +static void buffer_disconnect_signals (GtkEntry *entry); +static GtkEntryBuffer *get_buffer (GtkEntry *entry); + + G_DEFINE_TYPE_WITH_CODE (GtkEntry, gtk_entry, GTK_TYPE_WIDGET, G_IMPLEMENT_INTERFACE (GTK_TYPE_EDITABLE, gtk_entry_editable_init) @@ -599,13 +622,21 @@ gtk_entry_class_init (GtkEntryClass *class) quark_cursor_hadjustment = g_quark_from_static_string ("gtk-hadjustment"); quark_capslock_feedback = g_quark_from_static_string ("gtk-entry-capslock-feedback"); + g_object_class_install_property (gobject_class, + PROP_BUFFER, + g_param_spec_object ("buffer", + P_("Text Buffer"), + P_("Text buffer object which actually stores entry text"), + GTK_TYPE_ENTRY_BUFFER, + GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_object_class_install_property (gobject_class, PROP_CURSOR_POSITION, g_param_spec_int ("cursor-position", P_("Cursor Position"), P_("The current position of the insertion cursor in chars"), 0, - MAX_SIZE, + GTK_ENTRY_BUFFER_MAX_SIZE, 0, GTK_PARAM_READABLE)); @@ -615,7 +646,7 @@ gtk_entry_class_init (GtkEntryClass *class) P_("Selection Bound"), P_("The position of the opposite end of the selection from the cursor in chars"), 0, - MAX_SIZE, + GTK_ENTRY_BUFFER_MAX_SIZE, 0, GTK_PARAM_READABLE)); @@ -633,7 +664,7 @@ gtk_entry_class_init (GtkEntryClass *class) P_("Maximum length"), P_("Maximum number of characters for this entry. Zero if no maximum"), 0, - MAX_SIZE, + GTK_ENTRY_BUFFER_MAX_SIZE, 0, GTK_PARAM_READWRITE)); g_object_class_install_property (gobject_class, @@ -1200,7 +1231,7 @@ gtk_entry_class_init (GtkEntryClass *class) GTK_PARAM_READABLE)); /** - * GtkEntry::progress-border: + * GtkEntry:progress-border: * * The border around the progress bar in the entry. * @@ -1214,7 +1245,7 @@ gtk_entry_class_init (GtkEntryClass *class) GTK_PARAM_READABLE)); /** - * GtkEntry::invisible-char: + * GtkEntry:invisible-char: * * The invisible character is used when masking entry contents (in * \"password mode\")"). When it is not explicitly set with the @@ -1225,7 +1256,7 @@ gtk_entry_class_init (GtkEntryClass *class) * This style property allows the theme to prepend a character * to the list of candidates. * - * Since: 2.22 + * Since: 2.18 */ gtk_widget_class_install_style_property (widget_class, g_param_spec_unichar ("invisible-char", @@ -1754,6 +1785,10 @@ gtk_entry_set_property (GObject *object, switch (prop_id) { + case PROP_BUFFER: + gtk_entry_set_buffer (entry, g_value_get_object (value)); + break; + case PROP_EDITABLE: { gboolean new_value = g_value_get_boolean (value); @@ -1969,6 +2004,10 @@ gtk_entry_get_property (GObject *object, switch (prop_id) { + case PROP_BUFFER: + g_value_set_object (value, gtk_entry_get_buffer (entry)); + break; + case PROP_CURSOR_POSITION: g_value_set_int (value, entry->current_pos); break; @@ -1982,7 +2021,7 @@ gtk_entry_get_property (GObject *object, break; case PROP_MAX_LENGTH: - g_value_set_int (value, entry->text_max_length); + g_value_set_int (value, gtk_entry_buffer_get_max_length (get_buffer (entry))); break; case PROP_VISIBILITY: @@ -2034,7 +2073,7 @@ gtk_entry_get_property (GObject *object, break; case PROP_TEXT_LENGTH: - g_value_set_uint (value, entry->text_length); + g_value_set_uint (value, gtk_entry_buffer_get_length (get_buffer (entry))); break; case PROP_INVISIBLE_CHAR_SET: @@ -2216,12 +2255,8 @@ static void gtk_entry_init (GtkEntry *entry) { GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry); - - GTK_WIDGET_SET_FLAGS (entry, GTK_CAN_FOCUS); - entry->text_size = MIN_SIZE; - entry->text = g_malloc (entry->text_size); - entry->text[0] = '\0'; + GTK_WIDGET_SET_FLAGS (entry, GTK_CAN_FOCUS); entry->editable = TRUE; entry->visible = TRUE; @@ -2258,6 +2293,7 @@ gtk_entry_init (GtkEntry *entry) G_CALLBACK (gtk_entry_retrieve_surrounding_cb), entry); g_signal_connect (entry->im_context, "delete-surrounding", G_CALLBACK (gtk_entry_delete_surrounding_cb), entry); + } static gint @@ -2361,24 +2397,12 @@ emit_changed (GtkEntry *entry) priv->real_changed = TRUE; } -/* - * Overwrite a memory that might contain sensitive information. - */ -static void -trash_area (gchar *area, gsize len) -{ - volatile gchar *varea = (volatile gchar *)area; - while (len-- > 0) - *varea++ = 0; -} - static void gtk_entry_destroy (GtkObject *object) { GtkEntry *entry = GTK_ENTRY (object); - entry->n_bytes = 0; - entry->current_pos = entry->selection_bound = entry->text_length = 0; + entry->current_pos = entry->selection_bound = 0; _gtk_entry_reset_im_context (entry); gtk_entry_reset_layout (entry); @@ -2394,12 +2418,6 @@ gtk_entry_destroy (GtkObject *object) entry->recompute_idle = 0; } - if (!entry->visible) - { - /* We want to trash the text here because the entry might be leaked. */ - trash_area (entry->text, strlen (entry->text)); - } - GTK_OBJECT_CLASS (gtk_entry_parent_class)->destroy (object); } @@ -2452,21 +2470,98 @@ gtk_entry_finalize (GObject *object) if (entry->recompute_idle) g_source_remove (entry->recompute_idle); - entry->text_size = 0; - - if (entry->text) - { - if (!entry->visible) - trash_area (entry->text, strlen (entry->text)); - g_free (entry->text); - entry->text = NULL; - } - g_free (priv->im_module); + /* COMPAT: entry->text is a deprecated field, and the allocation + is owned by the buffer. */ + + gtk_entry_set_buffer (entry, NULL); + G_OBJECT_CLASS (gtk_entry_parent_class)->finalize (object); } +static DisplayMode +gtk_entry_get_display_mode (GtkEntry *entry) +{ + GtkEntryPrivate *priv; + if (entry->visible) + return DISPLAY_NORMAL; + priv = GTK_ENTRY_GET_PRIVATE (entry); + if (entry->invisible_char == 0 && priv->invisible_char_set) + return DISPLAY_BLANK; + return DISPLAY_INVISIBLE; +} + +static gchar* +gtk_entry_get_display_text (GtkEntry *entry, + gint start_pos, + gint end_pos) +{ + GtkEntryPasswordHint *password_hint; + GtkEntryPrivate *priv; + gunichar invisible_char; + const gchar *start; + const gchar *end; + const gchar *text; + gchar char_str[7]; + gint char_len; + GString *str; + guint length; + gint i; + + priv = GTK_ENTRY_GET_PRIVATE (entry); + text = gtk_entry_buffer_get_text (get_buffer (entry)); + length = gtk_entry_buffer_get_length (get_buffer (entry)); + + if (end_pos < 0) + end_pos = length; + if (start_pos > length) + start_pos = length; + + if (end_pos <= start_pos) + return g_strdup (""); + else if (entry->visible) + { + start = g_utf8_offset_to_pointer (text, start_pos); + end = g_utf8_offset_to_pointer (start, end_pos - start_pos); + return g_strndup (start, end - start); + } + else + { + str = g_string_sized_new (length * 2); + + /* Figure out what our invisible char is and encode it */ + if (!entry->invisible_char) + invisible_char = priv->invisible_char_set ? ' ' : '*'; + else + invisible_char = entry->invisible_char; + char_len = g_unichar_to_utf8 (invisible_char, char_str); + + /* + * Add hidden characters for each character in the text + * buffer. If there is a password hint, then keep that + * character visible. + */ + + password_hint = g_object_get_qdata (G_OBJECT (entry), quark_password_hint); + for (i = start_pos; i < end_pos; ++i) + { + if (password_hint && i == password_hint->position) + { + start = g_utf8_offset_to_pointer (text, i); + g_string_append_len (str, start, g_utf8_next_char (start) - start); + } + else + { + g_string_append_len (str, char_str, char_len); + } + } + + return g_string_free (str, FALSE); + } + +} + static void update_cursors (GtkWidget *widget) { @@ -2561,9 +2656,6 @@ construct_icon_info (GtkWidget *widget, if (GTK_WIDGET_REALIZED (widget)) realize_icon_info (widget, icon_pos); - if (GTK_WIDGET_MAPPED (widget)) - gdk_window_show_unraised (icon_info->window); - return icon_info; } @@ -3350,10 +3442,11 @@ gtk_entry_expose (GtkWidget *widget, gtk_entry_draw_text (GTK_ENTRY (widget)); - if ((entry->visible || entry->invisible_char != 0) && + /* When no text is being displayed at all, don't show the cursor */ + if (gtk_entry_get_display_mode (entry) != DISPLAY_BLANK && GTK_WIDGET_HAS_FOCUS (widget) && - entry->selection_bound == entry->current_pos && entry->cursor_visible) - gtk_entry_draw_cursor (GTK_ENTRY (widget), CURSOR_STANDARD); + entry->selection_bound == entry->current_pos && entry->cursor_visible) + gtk_entry_draw_cursor (GTK_ENTRY (widget), CURSOR_STANDARD); } else { @@ -3426,6 +3519,10 @@ gtk_entry_leave_notify (GtkWidget *widget, if (icon_info != NULL && event->window == icon_info->window) { + /* a grab means that we may never see the button release */ + if (event->mode == GDK_CROSSING_GRAB || event->mode == GDK_CROSSING_GTK_GRAB) + icon_info->pressed = FALSE; + if (should_prelight (entry, i)) { icon_info->prelight = FALSE; @@ -3822,7 +3919,7 @@ gtk_entry_motion_notify (GtkWidget *widget, if (entry->in_drag) { - if (entry->visible && + if (gtk_entry_get_display_mode (entry) == DISPLAY_NORMAL && gtk_drag_check_threshold (widget, entry->drag_start_x, entry->drag_start_y, event->x + entry->scroll_offset, event->y)) @@ -3868,7 +3965,7 @@ gtk_entry_motion_notify (GtkWidget *widget, if (event->y < 0) tmp_pos = 0; else if (event->y >= height) - tmp_pos = entry->text_length; + tmp_pos = gtk_entry_buffer_get_length (get_buffer (entry)); else tmp_pos = gtk_entry_find_position (entry, event->x + entry->scroll_offset); @@ -4156,30 +4253,14 @@ gtk_entry_insert_text (GtkEditable *editable, gint new_text_length, gint *position) { - GtkEntry *entry = GTK_ENTRY (editable); - gchar buf[64]; - gchar *text; - - if (*position < 0 || *position > entry->text_length) - *position = entry->text_length; - g_object_ref (editable); - - if (new_text_length <= 63) - text = buf; - else - text = g_new (gchar, new_text_length + 1); - text[new_text_length] = '\0'; - strncpy (text, new_text, new_text_length); + /* + * The incoming text may a password or other secret. We make sure + * not to copy it into temporary buffers. + */ - g_signal_emit_by_name (editable, "insert-text", text, new_text_length, position); - - if (!entry->visible) - trash_area (text, new_text_length); - - if (new_text_length > 63) - g_free (text); + g_signal_emit_by_name (editable, "insert-text", new_text, new_text_length, position); g_object_unref (editable); } @@ -4189,15 +4270,6 @@ gtk_entry_delete_text (GtkEditable *editable, gint start_pos, gint end_pos) { - GtkEntry *entry = GTK_ENTRY (editable); - - if (end_pos < 0 || end_pos > entry->text_length) - end_pos = entry->text_length; - if (start_pos < 0) - start_pos = 0; - if (start_pos > end_pos) - start_pos = end_pos; - g_object_ref (editable); g_signal_emit_by_name (editable, "delete-text", start_pos, end_pos); @@ -4211,18 +4283,23 @@ gtk_entry_get_chars (GtkEditable *editable, gint end_pos) { GtkEntry *entry = GTK_ENTRY (editable); + const gchar *text; + gint text_length; gint start_index, end_index; - + + text = gtk_entry_buffer_get_text (get_buffer (entry)); + text_length = gtk_entry_buffer_get_length (get_buffer (entry)); + if (end_pos < 0) - end_pos = entry->text_length; + end_pos = text_length; - start_pos = MIN (entry->text_length, start_pos); - end_pos = MIN (entry->text_length, end_pos); + start_pos = MIN (text_length, start_pos); + end_pos = MIN (text_length, end_pos); - start_index = g_utf8_offset_to_pointer (entry->text, start_pos) - entry->text; - end_index = g_utf8_offset_to_pointer (entry->text, end_pos) - entry->text; + start_index = g_utf8_offset_to_pointer (text, start_pos) - entry->text; + end_index = g_utf8_offset_to_pointer (text, end_pos) - entry->text; - return g_strndup (entry->text + start_index, end_index - start_index); + return g_strndup (text + start_index, end_index - start_index); } static void @@ -4231,8 +4308,11 @@ gtk_entry_real_set_position (GtkEditable *editable, { GtkEntry *entry = GTK_ENTRY (editable); - if (position < 0 || position > entry->text_length) - position = entry->text_length; + guint length; + + length = gtk_entry_buffer_get_length (get_buffer (entry)); + if (position < 0 || position > length) + position = length; if (position != entry->current_pos || position != entry->selection_bound) @@ -4254,17 +4334,19 @@ gtk_entry_set_selection_bounds (GtkEditable *editable, gint end) { GtkEntry *entry = GTK_ENTRY (editable); + guint length; + length = gtk_entry_buffer_get_length (get_buffer (entry)); if (start < 0) - start = entry->text_length; + start = length; if (end < 0) - end = entry->text_length; + end = length; _gtk_entry_reset_im_context (entry); gtk_entry_set_positions (entry, - MIN (end, entry->text_length), - MIN (start, entry->text_length)); + MIN (end, length), + MIN (start, length)); gtk_entry_update_primary_selection (entry); } @@ -4405,12 +4487,24 @@ gtk_entry_start_editing (GtkCellEditable *cell_editable, static void gtk_entry_password_hint_free (GtkEntryPasswordHint *password_hint) { - if (password_hint->password_hint_timeout_id) - g_source_remove (password_hint->password_hint_timeout_id); + if (password_hint->source_id) + g_source_remove (password_hint->source_id); g_slice_free (GtkEntryPasswordHint, password_hint); } + +static gboolean +gtk_entry_remove_password_hint (gpointer data) +{ + GtkEntryPasswordHint *password_hint = g_object_get_qdata (data, quark_password_hint); + password_hint->position = -1; + + /* Force the string to be redrawn, but now without a visible character */ + gtk_entry_recompute (GTK_ENTRY (data)); + return FALSE; +} + /* Default signal handlers */ static void @@ -4419,82 +4513,58 @@ gtk_entry_real_insert_text (GtkEditable *editable, gint new_text_length, gint *position) { - GtkEntry *entry = GTK_ENTRY (editable); - gint index; + guint n_inserted; gint n_chars; - if (new_text_length < 0) - new_text_length = strlen (new_text); - n_chars = g_utf8_strlen (new_text, new_text_length); - if (entry->text_max_length > 0 && n_chars + entry->text_length > entry->text_max_length) - { - gtk_widget_error_bell (GTK_WIDGET (entry)); - n_chars = entry->text_max_length - entry->text_length; - new_text_length = g_utf8_offset_to_pointer (new_text, n_chars) - new_text; - } - if (new_text_length + entry->n_bytes + 1 > entry->text_size) - { - gsize prev_size = entry->text_size; + /* + * The actual insertion into the buffer. This will end up firing the + * following signal handlers: buffer_inserted_text(), buffer_notify_display_text(), + * buffer_notify_text(), buffer_notify_length() + */ + n_inserted = gtk_entry_buffer_insert_text (GTK_ENTRY_GET_PRIVATE (editable)->buffer, *position, new_text, n_chars); - while (new_text_length + entry->n_bytes + 1 > entry->text_size) - { - if (entry->text_size == 0) - entry->text_size = MIN_SIZE; - else - { - if (2 * (guint)entry->text_size < MAX_SIZE && - 2 * (guint)entry->text_size > entry->text_size) - entry->text_size *= 2; - else - { - entry->text_size = MAX_SIZE; - if (new_text_length > (gint)entry->text_size - (gint)entry->n_bytes - 1) - { - new_text_length = (gint)entry->text_size - (gint)entry->n_bytes - 1; - new_text_length = g_utf8_find_prev_char (new_text, new_text + new_text_length + 1) - new_text; - n_chars = g_utf8_strlen (new_text, new_text_length); - } - break; - } - } - } + if (n_inserted != n_chars) + gtk_widget_error_bell (GTK_WIDGET (editable)); - if (entry->visible) - entry->text = g_realloc (entry->text, entry->text_size); - else - { - /* Same thing, just slower and without leaving stuff in memory. */ - gchar *et_new = g_malloc (entry->text_size); - memcpy (et_new, entry->text, MIN (prev_size, entry->text_size)); - trash_area (entry->text, prev_size); - g_free (entry->text); - entry->text = et_new; - } - } + *position += n_inserted; +} - index = g_utf8_offset_to_pointer (entry->text, *position) - entry->text; +static void +gtk_entry_real_delete_text (GtkEditable *editable, + gint start_pos, + gint end_pos) +{ + /* + * The actual deletion from the buffer. This will end up firing the + * following signal handlers: buffer_deleted_text(), buffer_notify_display_text(), + * buffer_notify_text(), buffer_notify_length() + */ - g_memmove (entry->text + index + new_text_length, entry->text + index, entry->n_bytes - index); - memcpy (entry->text + index, new_text, new_text_length); + gtk_entry_buffer_delete_text (get_buffer (GTK_ENTRY (editable)), start_pos, end_pos - start_pos); +} - entry->n_bytes += new_text_length; - entry->text_length += n_chars; +/* GtkEntryBuffer signal handlers + */ +static void +buffer_inserted_text (GtkEntryBuffer *buffer, + guint position, + const gchar *chars, + guint n_chars, + GtkEntry *entry) +{ + guint password_hint_timeout; - /* NUL terminate for safety and convenience */ - entry->text[entry->n_bytes] = '\0'; - - if (entry->current_pos > *position) + if (entry->current_pos > position) entry->current_pos += n_chars; - - if (entry->selection_bound > *position) + + if (entry->selection_bound > position) entry->selection_bound += n_chars; - if (n_chars == 1 && !entry->visible && (new_text_length < PASSWORD_HINT_MAX)) + /* Calculate the password hint if it needs to be displayed. */ + if (n_chars == 1 && !entry->visible) { - guint password_hint_timeout; - g_object_get (gtk_widget_get_settings (GTK_WIDGET (entry)), "gtk-entry-password-hint-timeout", &password_hint_timeout, NULL); @@ -4503,87 +4573,115 @@ gtk_entry_real_insert_text (GtkEditable *editable, { GtkEntryPasswordHint *password_hint = g_object_get_qdata (G_OBJECT (entry), quark_password_hint); - if (!password_hint) { password_hint = g_slice_new0 (GtkEntryPasswordHint); - g_object_set_qdata_full (G_OBJECT (entry), quark_password_hint, - password_hint, - (GDestroyNotify) gtk_entry_password_hint_free); + g_object_set_qdata_full (G_OBJECT (entry), quark_password_hint, password_hint, + (GDestroyNotify)gtk_entry_password_hint_free); } - memset (&password_hint->password_hint, 0x0, PASSWORD_HINT_MAX); - password_hint->password_hint_length = new_text_length; - memcpy (&password_hint->password_hint, new_text, new_text_length); - password_hint->password_hint_position = *position + n_chars; - } + password_hint->position = position; + if (password_hint->source_id) + g_source_remove (password_hint->source_id); + password_hint->source_id = gdk_threads_add_timeout (password_hint_timeout, + (GSourceFunc)gtk_entry_remove_password_hint, entry); + } } - else - { - g_object_set_qdata (G_OBJECT (entry), quark_password_hint, NULL); - } - - *position += n_chars; - - gtk_entry_recompute (entry); - - emit_changed (entry); - g_object_notify (G_OBJECT (editable), "text"); - g_object_notify (G_OBJECT (editable), "text-length"); } static void -gtk_entry_real_delete_text (GtkEditable *editable, - gint start_pos, - gint end_pos) +buffer_deleted_text (GtkEntryBuffer *buffer, + guint position, + guint n_chars, + GtkEntry *entry) { - GtkEntry *entry = GTK_ENTRY (editable); + guint end_pos = position + n_chars; + gint selection_bound; + guint current_pos; - if (start_pos < 0) - start_pos = 0; - if (end_pos < 0 || end_pos > entry->text_length) - end_pos = entry->text_length; - - if (start_pos < end_pos) + current_pos = entry->current_pos; + if (current_pos > position) + current_pos -= MIN (current_pos, end_pos) - position; + + selection_bound = entry->selection_bound; + if (selection_bound > position) + selection_bound -= MIN (selection_bound, end_pos) - position; + + gtk_entry_set_positions (entry, current_pos, selection_bound); + + /* We might have deleted the selection */ + gtk_entry_update_primary_selection (entry); + + /* Disable the password hint if one exists. */ + if (!entry->visible) { - gint start_index = g_utf8_offset_to_pointer (entry->text, start_pos) - entry->text; - gint end_index = g_utf8_offset_to_pointer (entry->text, end_pos) - entry->text; - gint current_pos; - gint selection_bound; - - g_memmove (entry->text + start_index, entry->text + end_index, entry->n_bytes + 1 - end_index); - entry->text_length -= (end_pos - start_pos); - entry->n_bytes -= (end_index - start_index); - - /* In password-mode, make sure we don't leave anything sensitive after - * the terminating zero. Note, that the terminating zero already trashed - * one byte. - */ - if (!entry->visible) - trash_area (entry->text + entry->n_bytes + 1, end_index - start_index - 1); - - current_pos = entry->current_pos; - if (current_pos > start_pos) - current_pos -= MIN (current_pos, end_pos) - start_pos; - - selection_bound = entry->selection_bound; - if (selection_bound > start_pos) - selection_bound -= MIN (selection_bound, end_pos) - start_pos; - - gtk_entry_set_positions (entry, current_pos, selection_bound); - - /* We might have deleted the selection - */ - gtk_entry_update_primary_selection (entry); - - gtk_entry_recompute (entry); - - emit_changed (entry); - g_object_notify (G_OBJECT (editable), "text"); - g_object_notify (G_OBJECT (editable), "text-length"); + GtkEntryPasswordHint *password_hint = g_object_get_qdata (G_OBJECT (entry), + quark_password_hint); + if (password_hint) + { + if (password_hint->source_id) + g_source_remove (password_hint->source_id); + password_hint->source_id = 0; + password_hint->position = -1; + } } } +static void +buffer_notify_text (GtkEntryBuffer *buffer, + GParamSpec *spec, + GtkEntry *entry) +{ + /* COMPAT: Deprecated, not used. This struct field will be removed in GTK+ 3.x */ + entry->text = (gchar*)gtk_entry_buffer_get_text (buffer); + + gtk_entry_recompute (entry); + emit_changed (entry); + g_object_notify (G_OBJECT (entry), "text"); +} + +static void +buffer_notify_length (GtkEntryBuffer *buffer, + GParamSpec *spec, + GtkEntry *entry) +{ + /* COMPAT: Deprecated, not used. This struct field will be removed in GTK+ 3.x */ + entry->text_length = gtk_entry_buffer_get_length (buffer); + + g_object_notify (G_OBJECT (entry), "text-length"); +} + +static void +buffer_notify_max_length (GtkEntryBuffer *buffer, + GParamSpec *spec, + GtkEntry *entry) +{ + /* COMPAT: Deprecated, not used. This struct field will be removed in GTK+ 3.x */ + entry->text_max_length = gtk_entry_buffer_get_max_length (buffer); + + g_object_notify (G_OBJECT (entry), "max-length"); +} + +static void +buffer_connect_signals (GtkEntry *entry) +{ + g_signal_connect (get_buffer (entry), "inserted-text", G_CALLBACK (buffer_inserted_text), entry); + g_signal_connect (get_buffer (entry), "deleted-text", G_CALLBACK (buffer_deleted_text), entry); + g_signal_connect (get_buffer (entry), "notify::text", G_CALLBACK (buffer_notify_text), entry); + g_signal_connect (get_buffer (entry), "notify::length", G_CALLBACK (buffer_notify_length), entry); + g_signal_connect (get_buffer (entry), "notify::max-length", G_CALLBACK (buffer_notify_max_length), entry); +} + +static void +buffer_disconnect_signals (GtkEntry *entry) +{ + g_signal_handlers_disconnect_by_func (get_buffer (entry), buffer_inserted_text, entry); + g_signal_handlers_disconnect_by_func (get_buffer (entry), buffer_deleted_text, entry); + g_signal_handlers_disconnect_by_func (get_buffer (entry), buffer_notify_text, entry); + g_signal_handlers_disconnect_by_func (get_buffer (entry), buffer_notify_length, entry); + g_signal_handlers_disconnect_by_func (get_buffer (entry), buffer_notify_max_length, entry); +} + /* Compute the X position for an offset that corresponds to the "more important * cursor position for that offset. We use this when trying to guess to which * end of the selection we should go to when the user hits the left or @@ -4622,6 +4720,7 @@ gtk_entry_move_cursor (GtkEntry *entry, gboolean extend_selection) { gint new_pos = entry->current_pos; + GtkEntryPrivate *priv; _gtk_entry_reset_im_context (entry); @@ -4653,7 +4752,8 @@ gtk_entry_move_cursor (GtkEntry *entry, case GTK_MOVEMENT_DISPLAY_LINE_ENDS: case GTK_MOVEMENT_PARAGRAPH_ENDS: case GTK_MOVEMENT_BUFFER_ENDS: - new_pos = count < 0 ? 0 : entry->text_length; + priv = GTK_ENTRY_GET_PRIVATE (entry); + new_pos = count < 0 ? 0 : gtk_entry_buffer_get_length (get_buffer (entry)); break; case GTK_MOVEMENT_DISPLAY_LINES: case GTK_MOVEMENT_PARAGRAPHS: @@ -4710,7 +4810,8 @@ gtk_entry_move_cursor (GtkEntry *entry, case GTK_MOVEMENT_DISPLAY_LINE_ENDS: case GTK_MOVEMENT_PARAGRAPH_ENDS: case GTK_MOVEMENT_BUFFER_ENDS: - new_pos = count < 0 ? 0 : entry->text_length; + priv = GTK_ENTRY_GET_PRIVATE (entry); + new_pos = count < 0 ? 0 : gtk_entry_buffer_get_length (get_buffer (entry)); if (entry->current_pos == new_pos) gtk_widget_error_bell (GTK_WIDGET (entry)); break; @@ -4754,7 +4855,7 @@ gtk_entry_delete_from_cursor (GtkEntry *entry, GtkEditable *editable = GTK_EDITABLE (entry); gint start_pos = entry->current_pos; gint end_pos = entry->current_pos; - gint old_n_bytes = entry->n_bytes; + gint old_n_bytes = gtk_entry_buffer_get_bytes (get_buffer (entry)); _gtk_entry_reset_im_context (entry); @@ -4820,7 +4921,7 @@ gtk_entry_delete_from_cursor (GtkEntry *entry, break; } - if (entry->n_bytes == old_n_bytes) + if (gtk_entry_buffer_get_bytes (get_buffer (entry)) == old_n_bytes) gtk_widget_error_bell (GTK_WIDGET (entry)); gtk_entry_pend_cursor_blink (entry); @@ -4834,7 +4935,7 @@ gtk_entry_backspace (GtkEntry *entry) _gtk_entry_reset_im_context (entry); - if (!entry->editable || !entry->text) + if (!entry->editable) { gtk_widget_error_bell (GTK_WIDGET (entry)); return; @@ -4856,16 +4957,15 @@ gtk_entry_backspace (GtkEntry *entry) pango_layout_get_log_attrs (layout, &log_attrs, &n_attrs); - if (entry->visible && - log_attrs[entry->current_pos].backspace_deletes_character) + /* Deleting parts of characters */ + if (log_attrs[entry->current_pos].backspace_deletes_character) { gchar *cluster_text; gchar *normalized_text; glong len; - cluster_text = gtk_editable_get_chars (editable, - prev_pos, - entry->current_pos); + cluster_text = gtk_entry_get_display_text (entry, prev_pos, + entry->current_pos); normalized_text = g_utf8_normalize (cluster_text, strlen (cluster_text), G_NORMALIZE_NFD); @@ -4915,7 +5015,7 @@ gtk_entry_copy_clipboard (GtkEntry *entry) return; } - str = gtk_entry_get_public_chars (entry, start, end); + str = gtk_entry_get_display_text (entry, start, end); gtk_clipboard_set_text (gtk_widget_get_clipboard (GTK_WIDGET (entry), GDK_SELECTION_CLIPBOARD), str, -1); @@ -5053,10 +5153,13 @@ static gboolean gtk_entry_retrieve_surrounding_cb (GtkIMContext *context, GtkEntry *entry) { - gtk_im_context_set_surrounding (context, - entry->text, - entry->n_bytes, - g_utf8_offset_to_pointer (entry->text, entry->current_pos) - entry->text); + gchar *text; + + /* XXXX ??? does this even make sense when text is not visible? Should we return FALSE? */ + text = gtk_entry_get_display_text (entry, 0, -1); + gtk_im_context_set_surrounding (context, text, strlen (text), /* Length in bytes */ + g_utf8_offset_to_pointer (text, entry->current_pos) - text); + g_free (text); return TRUE; } @@ -5215,34 +5318,6 @@ gtk_entry_recompute (GtkEntry *entry) } } -static void -append_char (GString *str, - gunichar ch, - gint count) -{ - gint i; - gint char_len; - gchar buf[7]; - - char_len = g_unichar_to_utf8 (ch, buf); - - i = 0; - while (i < count) - { - g_string_append_len (str, buf, char_len); - ++i; - } -} - -static gboolean -gtk_entry_remove_password_hint (gpointer data) -{ - /* Force the string to be redrawn, but now without a visible character */ - gtk_entry_recompute (GTK_ENTRY (data)); - - return FALSE; -} - static PangoLayout * gtk_entry_create_layout (GtkEntry *entry, gboolean include_preedit) @@ -5250,13 +5325,19 @@ gtk_entry_create_layout (GtkEntry *entry, GtkWidget *widget = GTK_WIDGET (entry); PangoLayout *layout = gtk_widget_create_pango_layout (widget, NULL); PangoAttrList *tmp_attrs = pango_attr_list_new (); - + gchar *preedit_string = NULL; gint preedit_length = 0; PangoAttrList *preedit_attrs = NULL; + gchar *display; + guint n_bytes; + pango_layout_set_single_paragraph_mode (layout, TRUE); + display = gtk_entry_get_display_text (entry, 0, -1); + n_bytes = strlen (display); + if (include_preedit) { gtk_im_context_get_preedit_string (entry->im_context, @@ -5266,32 +5347,10 @@ gtk_entry_create_layout (GtkEntry *entry, if (preedit_length) { - GString *tmp_string = g_string_new (NULL); + GString *tmp_string = g_string_new (display); + gint cursor_index = g_utf8_offset_to_pointer (display, entry->current_pos) - display; - gint cursor_index = g_utf8_offset_to_pointer (entry->text, entry->current_pos) - entry->text; - - if (entry->visible) - { - g_string_prepend_len (tmp_string, entry->text, entry->n_bytes); - g_string_insert (tmp_string, cursor_index, preedit_string); - } - else - { - gint ch_len; - gunichar invisible_char; - - if (entry->invisible_char != 0) - invisible_char = entry->invisible_char; - else - invisible_char = ' '; /* just pick a char */ - - ch_len = g_utf8_strlen (entry->text, entry->n_bytes); - append_char (tmp_string, invisible_char, ch_len); - cursor_index = - g_utf8_offset_to_pointer (tmp_string->str, entry->current_pos) - - tmp_string->str; - g_string_insert (tmp_string, cursor_index, preedit_string); - } + g_string_insert (tmp_string, cursor_index, preedit_string); pango_layout_set_text (layout, tmp_string->str, tmp_string->len); @@ -5304,9 +5363,8 @@ gtk_entry_create_layout (GtkEntry *entry, { PangoDirection pango_dir; - if (entry->visible) - pango_dir = pango_find_base_dir (entry->text, entry->n_bytes); - + if (gtk_entry_get_display_mode (entry) == DISPLAY_NORMAL) + pango_dir = pango_find_base_dir (display, n_bytes); else pango_dir = PANGO_DIRECTION_NEUTRAL; @@ -5334,78 +5392,15 @@ gtk_entry_create_layout (GtkEntry *entry, pango_dir); entry->resolved_dir = pango_dir; - - if (entry->visible) - { - pango_layout_set_text (layout, entry->text, entry->n_bytes); - } - else - { - GString *str = g_string_new (NULL); - gunichar invisible_char; - guint password_hint_timeout; - GtkEntryPasswordHint *password_hint; - g_object_get (gtk_widget_get_settings (widget), - "gtk-entry-password-hint-timeout", &password_hint_timeout, - NULL); - - if (entry->invisible_char != 0) - invisible_char = entry->invisible_char; - else - invisible_char = ' '; /* just pick a char */ - - password_hint = g_object_get_qdata (G_OBJECT (entry), - quark_password_hint); - - if (password_hint && password_hint->password_hint_timeout_id) - { - g_source_remove (password_hint->password_hint_timeout_id); - password_hint->password_hint_timeout_id = 0; - } - - if (password_hint_timeout == 0 || password_hint == NULL || - (password_hint && password_hint->password_hint_length == 0)) - { - append_char (str, invisible_char, entry->text_length); - } - else if (password_hint) - { - /* Draw hidden characters upto the inserted position, - * then the real thing, pad up to full length - */ - if (password_hint->password_hint_position > 1) - append_char (str, invisible_char, - password_hint->password_hint_position - 1); - - g_string_append_len (str, password_hint->password_hint, - password_hint->password_hint_length); - - if (password_hint->password_hint_position < entry->text_length) - append_char (str, invisible_char, - entry->text_length - - password_hint->password_hint_position); - - /* Now remove this last input character, don't need - * it anymore - */ - memset (password_hint->password_hint, 0, PASSWORD_HINT_MAX); - password_hint->password_hint_length = 0; - - password_hint->password_hint_timeout_id = - gdk_threads_add_timeout (password_hint_timeout, - (GSourceFunc) gtk_entry_remove_password_hint, - entry); - } - - pango_layout_set_text (layout, str->str, str->len); - g_string_free (str, TRUE); - } + pango_layout_set_text (layout, display, n_bytes); } pango_layout_set_attributes (layout, tmp_attrs); g_free (preedit_string); + g_free (display); + if (preedit_attrs) pango_attr_list_unref (preedit_attrs); @@ -5543,7 +5538,8 @@ gtk_entry_draw_text (GtkEntry *entry) GtkWidget *widget = GTK_WIDGET (entry); cairo_t *cr; - if (!entry->visible && entry->invisible_char == 0) + /* Nothing to display at all */ + if (gtk_entry_get_display_mode (entry) == DISPLAY_BLANK) return; if (GTK_WIDGET_DRAWABLE (entry)) @@ -5809,7 +5805,10 @@ gtk_entry_get_cursor_locations (GtkEntry *entry, gint *strong_x, gint *weak_x) { - if (!entry->visible && !entry->invisible_char) + DisplayMode mode = gtk_entry_get_display_mode (entry); + + /* Nothing to display at all, so no cursor is relevant */ + if (mode == DISPLAY_BLANK) { if (strong_x) *strong_x = 0; @@ -5834,11 +5833,11 @@ gtk_entry_get_cursor_locations (GtkEntry *entry, if (entry->dnd_position > entry->current_pos) { - if (entry->visible) + if (mode == DISPLAY_NORMAL) index += entry->preedit_length; else { - gint preedit_len_chars = g_utf8_strlen (text, -1) - entry->text_length; + gint preedit_len_chars = g_utf8_strlen (text, -1) - gtk_entry_buffer_get_length (get_buffer (entry)); index += preedit_len_chars * g_unichar_to_utf8 (entry->invisible_char, NULL); } } @@ -6043,13 +6042,16 @@ gtk_entry_move_logically (GtkEntry *entry, gint count) { gint new_pos = start; + guint length; + + length = gtk_entry_buffer_get_length (get_buffer (entry)); /* Prevent any leak of information */ - if (!entry->visible) + if (gtk_entry_get_display_mode (entry) != DISPLAY_NORMAL) { - new_pos = CLAMP (start + count, 0, entry->text_length); + new_pos = CLAMP (start + count, 0, length); } - else if (entry->text) + else { PangoLayout *layout = gtk_entry_ensure_layout (entry, FALSE); PangoLogAttr *log_attrs; @@ -6057,11 +6059,11 @@ gtk_entry_move_logically (GtkEntry *entry, pango_layout_get_log_attrs (layout, &log_attrs, &n_attrs); - while (count > 0 && new_pos < entry->text_length) + while (count > 0 && new_pos < length) { do new_pos++; - while (new_pos < entry->text_length && !log_attrs[new_pos].is_cursor_position); + while (new_pos < length && !log_attrs[new_pos].is_cursor_position); count--; } @@ -6086,13 +6088,16 @@ gtk_entry_move_forward_word (GtkEntry *entry, gboolean allow_whitespace) { gint new_pos = start; + guint length; + + length = gtk_entry_buffer_get_length (get_buffer (entry)); /* Prevent any leak of information */ - if (!entry->visible) + if (gtk_entry_get_display_mode (entry) != DISPLAY_NORMAL) { - new_pos = entry->text_length; + new_pos = length; } - else if (entry->text && (new_pos < entry->text_length)) + else if (new_pos < length) { PangoLayout *layout = gtk_entry_ensure_layout (entry, FALSE); PangoLogAttr *log_attrs; @@ -6121,11 +6126,11 @@ gtk_entry_move_backward_word (GtkEntry *entry, gint new_pos = start; /* Prevent any leak of information */ - if (!entry->visible) + if (gtk_entry_get_display_mode (entry) != DISPLAY_NORMAL) { new_pos = 0; } - else if (entry->text && start > 0) + else if (start > 0) { PangoLayout *layout = gtk_entry_ensure_layout (entry, FALSE); PangoLogAttr *log_attrs; @@ -6186,30 +6191,6 @@ gtk_entry_select_line (GtkEntry *entry) gtk_editable_select_region (GTK_EDITABLE (entry), 0, -1); } -/* - * Like gtk_editable_get_chars, but handle not-visible entries - * correctly. - */ -static char * -gtk_entry_get_public_chars (GtkEntry *entry, - gint start, - gint end) -{ - if (end < 0) - end = entry->text_length; - - if (entry->visible) - return gtk_editable_get_chars (GTK_EDITABLE (entry), start, end); - else if (!entry->invisible_char) - return g_strdup (""); - else - { - GString *str = g_string_new (NULL); - append_char (str, entry->invisible_char, end - start); - return g_string_free (str, FALSE); - } -} - static gint truncate_multiline (const gchar *text) { @@ -6253,7 +6234,8 @@ paste_received (GtkClipboard *clipboard, length = truncate_multiline (text); /* only complete if the selection is at the end */ - popup_completion = (entry->text_length == MAX (entry->current_pos, entry->selection_bound)); + popup_completion = (gtk_entry_buffer_get_length (get_buffer (entry)) == + MAX (entry->current_pos, entry->selection_bound)); if (completion) { @@ -6303,7 +6285,7 @@ primary_get_cb (GtkClipboard *clipboard, if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &start, &end)) { - gchar *str = gtk_entry_get_public_chars (entry, start, end); + gchar *str = gtk_entry_get_display_text (entry, start, end); gtk_selection_data_set_text (selection_data, str, -1); g_free (str); } @@ -6545,6 +6527,23 @@ gtk_entry_new (void) return g_object_new (GTK_TYPE_ENTRY, NULL); } +/** + * gtk_entry_new_with_buffer: + * @buffer: The buffer to use for the new #GtkEntry. + * + * Creates a new entry with the specified text buffer. + * + * Return value: a new #GtkEntry + * + * Since: 2.18 + */ +GtkWidget* +gtk_entry_new_with_buffer (GtkEntryBuffer *buffer) +{ + g_return_val_if_fail (GTK_IS_ENTRY_BUFFER (buffer), NULL); + return g_object_new (GTK_TYPE_ENTRY, "buffer", buffer, NULL); +} + /** * gtk_entry_new_with_max_length: * @max: the maximum length of the entry, or 0 for no maximum. @@ -6562,14 +6561,112 @@ gtk_entry_new_with_max_length (gint max) { GtkEntry *entry; - max = CLAMP (max, 0, MAX_SIZE); + max = CLAMP (max, 0, GTK_ENTRY_BUFFER_MAX_SIZE); entry = g_object_new (GTK_TYPE_ENTRY, NULL); - entry->text_max_length = max; + gtk_entry_buffer_set_max_length (get_buffer (entry), max); return GTK_WIDGET (entry); } + +static GtkEntryBuffer* +get_buffer (GtkEntry *entry) +{ + GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry); + + if (priv->buffer == NULL) + { + GtkEntryBuffer *buffer; + buffer = gtk_entry_buffer_new (NULL, 0); + gtk_entry_set_buffer (entry, buffer); + g_object_unref (buffer); + } + + return priv->buffer; +} + +/** + * gtk_entry_get_buffer: + * @entry: a #GtkEntry + * + * Get the #GtkEntryBuffer object which holds the text for + * this widget. + * + * Since: 2.18 + * + * Returns: A #GtkEntryBuffer object. + */ +GtkEntryBuffer* +gtk_entry_get_buffer (GtkEntry *entry) +{ + g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL); + + return get_buffer (entry); +} + +/** + * gtk_entry_set_buffer: + * @entry: a #GtkEntry + * @buffer: a #GtkEntryBuffer + * + * Set the #GtkEntryBuffer object which holds the text for + * this widget. + * + * Since: 2.18 + */ +void +gtk_entry_set_buffer (GtkEntry *entry, + GtkEntryBuffer *buffer) +{ + GtkEntryPrivate *priv; + GObject *obj; + + g_return_if_fail (GTK_IS_ENTRY (entry)); + priv = GTK_ENTRY_GET_PRIVATE (entry); + + if (buffer) + { + g_return_if_fail (GTK_IS_ENTRY_BUFFER (buffer)); + g_object_ref (buffer); + } + + if (priv->buffer) + { + buffer_disconnect_signals (entry); + g_object_unref (priv->buffer); + + /* COMPAT: Deprecated. Not used. Setting these fields no longer necessary in GTK 3.x */ + entry->text = NULL; + entry->text_length = 0; + entry->text_max_length = 0; + } + + priv->buffer = buffer; + + if (priv->buffer) + { + buffer_connect_signals (entry); + + /* COMPAT: Deprecated. Not used. Setting these fields no longer necessary in GTK 3.x */ + entry->text = (char*)gtk_entry_buffer_get_text (priv->buffer); + entry->text_length = gtk_entry_buffer_get_length (priv->buffer); + entry->text_max_length = gtk_entry_buffer_get_max_length (priv->buffer); + } + + obj = G_OBJECT (entry); + g_object_freeze_notify (obj); + g_object_notify (obj, "buffer"); + g_object_notify (obj, "text"); + g_object_notify (obj, "text-length"); + g_object_notify (obj, "max-length"); + g_object_notify (obj, "visibility"); + g_object_notify (obj, "invisible-char"); + g_object_notify (obj, "invisible-char-set"); + g_object_thaw_notify (obj); +} + + /** * gtk_entry_set_text: * @entry: a #GtkEntry @@ -6577,6 +6674,8 @@ gtk_entry_new_with_max_length (gint max) * * Sets the text in the widget to the given * value, replacing the current contents. + * + * See gtk_entry_buffer_set_text(). */ void gtk_entry_set_text (GtkEntry *entry, @@ -6584,14 +6683,16 @@ gtk_entry_set_text (GtkEntry *entry, { gint tmp_pos; GtkEntryCompletion *completion; + GtkEntryPrivate *priv; g_return_if_fail (GTK_IS_ENTRY (entry)); g_return_if_fail (text != NULL); + priv = GTK_ENTRY_GET_PRIVATE (entry); /* Actually setting the text will affect the cursor and selection; * if the contents don't actually change, this will look odd to the user. */ - if (strcmp (entry->text, text) == 0) + if (strcmp (gtk_entry_buffer_get_text (get_buffer (entry)), text) == 0) return; completion = gtk_entry_get_completion (entry); @@ -6601,7 +6702,6 @@ gtk_entry_set_text (GtkEntry *entry, begin_change (entry); g_object_freeze_notify (G_OBJECT (entry)); gtk_editable_delete_text (GTK_EDITABLE (entry), 0, -1); - tmp_pos = 0; gtk_editable_insert_text (GTK_EDITABLE (entry), text, strlen (text), &tmp_pos); g_object_thaw_notify (G_OBJECT (entry)); @@ -6624,12 +6724,14 @@ void gtk_entry_append_text (GtkEntry *entry, const gchar *text) { + GtkEntryPrivate *priv; gint tmp_pos; g_return_if_fail (GTK_IS_ENTRY (entry)); g_return_if_fail (text != NULL); + priv = GTK_ENTRY_GET_PRIVATE (entry); - tmp_pos = entry->text_length; + tmp_pos = gtk_entry_buffer_get_length (get_buffer (entry)); gtk_editable_insert_text (GTK_EDITABLE (entry), text, -1, &tmp_pos); } @@ -6886,6 +6988,12 @@ gtk_entry_get_overwrite_mode (GtkEntry *entry) * Retrieves the contents of the entry widget. * See also gtk_editable_get_chars(). * + * This is equivalent to: + * + * + * gtk_entry_buffer_get_text (gtk_entry_get_buffer (entry)); + * + * * Return value: a pointer to the contents of the widget as a * string. This string points to internally allocated * storage in the widget and must not be freed, modified or @@ -6895,8 +7003,7 @@ G_CONST_RETURN gchar* gtk_entry_get_text (GtkEntry *entry) { g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL); - - return entry->text; + return gtk_entry_buffer_get_text (get_buffer (entry)); } /** @@ -6931,20 +7038,19 @@ gtk_entry_select_region (GtkEntry *entry, * Sets the maximum allowed length of the contents of the widget. If * the current contents are longer than the given length, then they * will be truncated to fit. + * + * This is equivalent to: + * + * + * gtk_entry_buffer_set_max_length (gtk_entry_get_buffer (entry), max); + * **/ void gtk_entry_set_max_length (GtkEntry *entry, gint max) { g_return_if_fail (GTK_IS_ENTRY (entry)); - - max = CLAMP (max, 0, MAX_SIZE); - - if (max > 0 && entry->text_length > max) - gtk_editable_delete_text (GTK_EDITABLE (entry), max, -1); - - entry->text_max_length = max; - g_object_notify (G_OBJECT (entry), "max-length"); + gtk_entry_buffer_set_max_length (get_buffer (entry), max); } /** @@ -6954,6 +7060,12 @@ gtk_entry_set_max_length (GtkEntry *entry, * Retrieves the maximum allowed length of the text in * @entry. See gtk_entry_set_max_length(). * + * This is equivalent to: + * + * + * gtk_entry_buffer_get_max_length (gtk_entry_get_buffer (entry)); + * + * * Return value: the maximum allowed number of characters * in #GtkEntry, or 0 if there is no maximum. **/ @@ -6961,8 +7073,7 @@ gint gtk_entry_get_max_length (GtkEntry *entry) { g_return_val_if_fail (GTK_IS_ENTRY (entry), 0); - - return entry->text_max_length; + return gtk_entry_buffer_get_max_length (get_buffer (entry)); } /** @@ -6972,6 +7083,12 @@ gtk_entry_get_max_length (GtkEntry *entry) * Retrieves the current length of the text in * @entry. * + * This is equivalent to: + * + * + * gtk_entry_buffer_get_length (gtk_entry_get_buffer (entry)); + * + * * Return value: the current number of characters * in #GtkEntry, or 0 if there are none. * @@ -6981,8 +7098,7 @@ guint16 gtk_entry_get_text_length (GtkEntry *entry) { g_return_val_if_fail (GTK_IS_ENTRY (entry), 0); - - return entry->text_length; + return gtk_entry_buffer_get_length (get_buffer (entry)); } /** @@ -7417,6 +7533,9 @@ gtk_entry_set_icon_from_pixbuf (GtkEntry *entry, g_object_notify (G_OBJECT (entry), "secondary-icon-pixbuf"); g_object_notify (G_OBJECT (entry), "secondary-icon-storage-type"); } + + if (GTK_WIDGET_MAPPED (entry)) + gdk_window_show_unraised (icon_info->window); } gtk_entry_ensure_pixbuf (entry, icon_pos); @@ -7481,6 +7600,9 @@ gtk_entry_set_icon_from_stock (GtkEntry *entry, g_object_notify (G_OBJECT (entry), "secondary-icon-stock"); g_object_notify (G_OBJECT (entry), "secondary-icon-storage-type"); } + + if (GTK_WIDGET_MAPPED (entry)) + gdk_window_show_unraised (icon_info->window); } gtk_entry_ensure_pixbuf (entry, icon_pos); @@ -7548,6 +7670,9 @@ gtk_entry_set_icon_from_icon_name (GtkEntry *entry, g_object_notify (G_OBJECT (entry), "secondary-icon-name"); g_object_notify (G_OBJECT (entry), "secondary-icon-storage-type"); } + + if (GTK_WIDGET_MAPPED (entry)) + gdk_window_show_unraised (icon_info->window); } gtk_entry_ensure_pixbuf (entry, icon_pos); @@ -7612,6 +7737,9 @@ gtk_entry_set_icon_from_gicon (GtkEntry *entry, g_object_notify (G_OBJECT (entry), "secondary-icon-gicon"); g_object_notify (G_OBJECT (entry), "secondary-icon-storage-type"); } + + if (GTK_WIDGET_MAPPED (entry)) + gdk_window_show_unraised (icon_info->window); } gtk_entry_ensure_pixbuf (entry, icon_pos); @@ -7855,9 +7983,14 @@ gtk_entry_set_icon_sensitive (GtkEntry *entry, { icon_info->insensitive = !sensitive; + icon_info->pressed = FALSE; + icon_info->prelight = FALSE; + if (GTK_WIDGET_REALIZED (GTK_WIDGET (entry))) update_cursors (GTK_WIDGET (entry)); + gtk_widget_queue_draw (GTK_WIDGET (entry)); + g_object_notify (G_OBJECT (entry), icon_pos == GTK_ENTRY_ICON_PRIMARY ? "primary-icon-sensitive" : "secondary-icon-sensitive"); } @@ -7981,6 +8114,8 @@ gtk_entry_get_icon_at_pos (GtkEntry *entry, * #GtkWidget::drag-begin signal to set a different icon. Note that you * have to use g_signal_connect_after() to ensure that your signal handler * gets executed after the default handler. + * + * Since: 2.16 */ void gtk_entry_set_icon_drag_source (GtkEntry *entry, @@ -8020,6 +8155,8 @@ gtk_entry_set_icon_drag_source (GtkEntry *entry, * * Returns: index of the icon which is the source of the current * DND operation, or -1. + * + * Since: 2.16 */ gint gtk_entry_get_current_icon_drag_source (GtkEntry *entry) @@ -8171,7 +8308,6 @@ gtk_entry_get_icon_tooltip_markup (GtkEntry *entry, { GtkEntryPrivate *priv; EntryIconInfo *icon_info; - gchar *text = NULL; g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL); g_return_val_if_fail (IS_VALID_ICON_POSITION (icon_pos), NULL); @@ -8391,6 +8527,7 @@ popup_targets_received (GtkClipboard *clipboard, if (GTK_WIDGET_REALIZED (entry)) { + DisplayMode mode; gboolean clipboard_contains_text; GtkWidget *menuitem; GtkWidget *submenu; @@ -8407,13 +8544,18 @@ popup_targets_received (GtkClipboard *clipboard, GTK_WIDGET (entry), popup_menu_detach); + mode = gtk_entry_get_display_mode (entry); append_action_signal (entry, entry->popup_menu, GTK_STOCK_CUT, "cut-clipboard", - entry->editable && entry->visible && entry->current_pos != entry->selection_bound); + entry->editable && mode == DISPLAY_NORMAL && + entry->current_pos != entry->selection_bound); + append_action_signal (entry, entry->popup_menu, GTK_STOCK_COPY, "copy-clipboard", - entry->visible && entry->current_pos != entry->selection_bound); + mode == DISPLAY_NORMAL && + entry->current_pos != entry->selection_bound); + append_action_signal (entry, entry->popup_menu, GTK_STOCK_PASTE, "paste-clipboard", entry->editable && clipboard_contains_text); - + menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_DELETE, NULL); gtk_widget_set_sensitive (menuitem, entry->editable && entry->current_pos != entry->selection_bound); g_signal_connect_swapped (menuitem, "activate", @@ -8762,7 +8904,7 @@ gtk_entry_drag_data_get (GtkWidget *widget, if (gtk_editable_get_selection_bounds (editable, &sel_start, &sel_end)) { - gchar *str = gtk_entry_get_public_chars (GTK_ENTRY (widget), sel_start, sel_end); + gchar *str = gtk_entry_get_display_text (GTK_ENTRY (widget), sel_start, sel_end); gtk_selection_data_set_text (selection_data, str, -1); @@ -9251,6 +9393,9 @@ keypress_completion_out: event->keyval == GDK_KP_Enter || event->keyval == GDK_Return) { + GtkTreeIter iter; + GtkTreeModel *model = NULL; + GtkTreeSelection *sel; gboolean retval = TRUE; _gtk_entry_reset_im_context (GTK_ENTRY (widget)); @@ -9258,9 +9403,6 @@ keypress_completion_out: if (completion->priv->current_selected < matches) { - GtkTreeIter iter; - GtkTreeModel *model = NULL; - GtkTreeSelection *sel; gboolean entry_set; sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (completion->priv->tree_view)); @@ -9292,15 +9434,18 @@ keypress_completion_out: } else if (completion->priv->current_selected - matches >= 0) { - GtkTreePath *path; + sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (completion->priv->action_view)); + if (gtk_tree_selection_get_selected (sel, &model, &iter)) + { + GtkTreePath *path; - _gtk_entry_reset_im_context (GTK_ENTRY (widget)); - - path = gtk_tree_path_new_from_indices (completion->priv->current_selected - matches, -1); - - g_signal_emit_by_name (completion, "action-activated", - gtk_tree_path_get_indices (path)[0]); - gtk_tree_path_free (path); + path = gtk_tree_path_new_from_indices (completion->priv->current_selected - matches, -1); + g_signal_emit_by_name (completion, "action-activated", + gtk_tree_path_get_indices (path)[0]); + gtk_tree_path_free (path); + } + else + retval = FALSE; } g_free (completion->priv->completion_prefix); @@ -9371,7 +9516,7 @@ accept_completion_callback (GtkEntry *entry) if (completion->priv->has_completion) gtk_editable_set_position (GTK_EDITABLE (entry), - entry->text_length); + gtk_entry_buffer_get_length (get_buffer (entry))); return FALSE; } @@ -9824,7 +9969,7 @@ keymap_state_changed (GdkKeymap *keymap, GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry); char *text = NULL; - if (!entry->visible && priv->caps_lock_warning) + if (gtk_entry_get_display_mode (entry) != DISPLAY_NORMAL && priv->caps_lock_warning) { if (gdk_keymap_get_caps_lock_state (keymap)) text = _("Caps Lock is on"); diff --git a/gtk/gtkentry.h b/gtk/gtkentry.h index be0444752b..d7f4bfb0f5 100644 --- a/gtk/gtkentry.h +++ b/gtk/gtkentry.h @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -66,7 +67,7 @@ struct _GtkEntry { GtkWidget widget; - gchar *GSEAL (text); + gchar *GSEAL (text); /* COMPAT: Deprecated, not used. Remove in GTK+ 3.x */ guint GSEAL (editable) : 1; guint GSEAL (visible) : 1; @@ -74,8 +75,8 @@ struct _GtkEntry guint GSEAL (in_drag) : 1; /* FIXME: Should be private? Dragging within the selection */ - guint16 GSEAL (text_length); /* length in use, in chars */ - guint16 GSEAL (text_max_length); + guint16 GSEAL (text_length); /* COMPAT: Deprecated, not used. Remove in GTK+ 3.x */ + guint16 GSEAL (text_max_length); /* COMPAT: Deprecated, not used. Remove in GTK+ 3.x */ /*< private >*/ GdkWindow *GSEAL (text_area); @@ -108,8 +109,8 @@ struct _GtkEntry gint GSEAL (ascent); /* font ascent in pango units */ gint GSEAL (descent); /* font descent in pango units */ - guint16 GSEAL (text_size); /* allocated size, in bytes */ - guint16 GSEAL (n_bytes); /* length in use, in bytes */ + guint16 GSEAL (x_text_size); /* allocated size, in bytes */ + guint16 GSEAL (x_n_bytes); /* length in use, in bytes */ guint16 GSEAL (preedit_length); /* length of preedit string, in bytes */ guint16 GSEAL (preedit_cursor); /* offset of cursor within preedit string, in chars */ @@ -164,6 +165,10 @@ struct _GtkEntryClass GType gtk_entry_get_type (void) G_GNUC_CONST; GtkWidget* gtk_entry_new (void); +GtkWidget* gtk_entry_new_with_buffer (GtkEntryBuffer *buffer); +GtkEntryBuffer* gtk_entry_get_buffer (GtkEntry *entry); +void gtk_entry_set_buffer (GtkEntry *entry, + GtkEntryBuffer *buffer); void gtk_entry_set_visibility (GtkEntry *entry, gboolean visible); gboolean gtk_entry_get_visibility (GtkEntry *entry); diff --git a/gtk/gtkentrybuffer.c b/gtk/gtkentrybuffer.c new file mode 100644 index 0000000000..57ce3b325a --- /dev/null +++ b/gtk/gtkentrybuffer.c @@ -0,0 +1,754 @@ +/* gtkentrybuffer.c + * Copyright (C) 2009 Stefan Walter + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include "gtkentrybuffer.h" +#include "gtkintl.h" +#include "gtkmarshalers.h" +#include "gtkprivate.h" +#include "gtkwidget.h" +#include "gtkalias.h" + +#include + +#include + +/** + * SECTION:gtkentrybuffer + * @title: GtkEntryBuffer + * @short_description: Text buffer for GtkEntry + * + * The #GtkEntryBuffer class contains the actual text displayed in a + * #GtkEntry widget. + * + * A single #GtkEntryBuffer object can be shared by multiple #GtkEntry + * widgets which will then share the same text content, but not the cursor + * position, visibility attributes, icon etc. + * + * #GtkEntryBuffer may be derived from. Such a derived class might allow + * text to be stored in an alternate location, such as non-pageable memory, + * useful in the case of important passwords. Or a derived class could + * integrate with an application's concept of undo/redo. + * + * Since: 2.18 + */ + +/* Initial size of buffer, in bytes */ +#define MIN_SIZE 16 + +enum { + PROP_0, + PROP_TEXT, + PROP_LENGTH, + PROP_MAX_LENGTH, +}; + +enum { + INSERTED_TEXT, + DELETED_TEXT, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +struct _GtkEntryBufferPrivate +{ + gint max_length; + + /* Only valid if this class is not derived */ + gchar *normal_text; + gsize normal_text_size; + gsize normal_text_bytes; + guint normal_text_chars; +}; + +G_DEFINE_TYPE (GtkEntryBuffer, gtk_entry_buffer, G_TYPE_OBJECT); + +/* -------------------------------------------------------------------------------- + * DEFAULT IMPLEMENTATIONS OF TEXT BUFFER + * + * These may be overridden by a derived class, behavior may be changed etc... + * The normal_text and normal_text_xxxx fields may not be valid when + * this class is derived from. + */ + +/* Overwrite a memory that might contain sensitive information. */ +static void +trash_area (gchar *area, + gsize len) +{ + volatile gchar *varea = (volatile gchar *)area; + while (len-- > 0) + *varea++ = 0; +} + +static const gchar* +gtk_entry_buffer_normal_get_text (GtkEntryBuffer *buffer, + gsize *n_bytes) +{ + if (n_bytes) + *n_bytes = buffer->priv->normal_text_bytes; + if (!buffer->priv->normal_text) + return ""; + return buffer->priv->normal_text; +} + +static guint +gtk_entry_buffer_normal_get_length (GtkEntryBuffer *buffer) +{ + return buffer->priv->normal_text_chars; +} + +static guint +gtk_entry_buffer_normal_insert_text (GtkEntryBuffer *buffer, + guint position, + const gchar *chars, + guint n_chars) +{ + GtkEntryBufferPrivate *pv = buffer->priv; + gsize prev_size; + gsize n_bytes; + gsize at; + + n_bytes = g_utf8_offset_to_pointer (chars, n_chars) - chars; + + /* Need more memory */ + if (n_bytes + pv->normal_text_bytes + 1 > pv->normal_text_size) + { + gchar *et_new; + + prev_size = pv->normal_text_size; + + /* Calculate our new buffer size */ + while (n_bytes + pv->normal_text_bytes + 1 > pv->normal_text_size) + { + if (pv->normal_text_size == 0) + pv->normal_text_size = MIN_SIZE; + else + { + if (2 * pv->normal_text_size < GTK_ENTRY_BUFFER_MAX_SIZE) + pv->normal_text_size *= 2; + else + { + pv->normal_text_size = GTK_ENTRY_BUFFER_MAX_SIZE; + if (n_bytes > pv->normal_text_size - pv->normal_text_bytes - 1) + { + n_bytes = pv->normal_text_size - pv->normal_text_bytes - 1; + n_bytes = g_utf8_find_prev_char (chars, chars + n_bytes + 1) - chars; + n_chars = g_utf8_strlen (chars, n_bytes); + } + break; + } + } + } + + /* Could be a password, so can't leave stuff in memory. */ + et_new = g_malloc (pv->normal_text_size); + memcpy (et_new, pv->normal_text, MIN (prev_size, pv->normal_text_size)); + trash_area (pv->normal_text, prev_size); + g_free (pv->normal_text); + pv->normal_text = et_new; + } + + /* Actual text insertion */ + at = g_utf8_offset_to_pointer (pv->normal_text, position) - pv->normal_text; + g_memmove (pv->normal_text + at + n_bytes, pv->normal_text + at, pv->normal_text_bytes - at); + memcpy (pv->normal_text + at, chars, n_bytes); + + /* Book keeping */ + pv->normal_text_bytes += n_bytes; + pv->normal_text_chars += n_chars; + pv->normal_text[pv->normal_text_bytes] = '\0'; + + gtk_entry_buffer_emit_inserted_text (buffer, position, chars, n_chars); + return n_chars; +} + +static guint +gtk_entry_buffer_normal_delete_text (GtkEntryBuffer *buffer, + guint position, + guint n_chars) +{ + GtkEntryBufferPrivate *pv = buffer->priv; + gsize start, end; + + if (position > pv->normal_text_chars) + position = pv->normal_text_chars; + if (position + n_chars > pv->normal_text_chars) + n_chars = pv->normal_text_chars - position; + + if (n_chars > 0) + { + start = g_utf8_offset_to_pointer (pv->normal_text, position) - pv->normal_text; + end = g_utf8_offset_to_pointer (pv->normal_text, position + n_chars) - pv->normal_text; + + g_memmove (pv->normal_text + start, pv->normal_text + end, pv->normal_text_bytes + 1 - end); + pv->normal_text_chars -= n_chars; + pv->normal_text_bytes -= (end - start); + + /* + * Could be a password, make sure we don't leave anything sensitive after + * the terminating zero. Note, that the terminating zero already trashed + * one byte. + */ + trash_area (pv->normal_text + pv->normal_text_bytes + 1, end - start - 1); + + gtk_entry_buffer_emit_deleted_text (buffer, position, n_chars); + } + + return n_chars; +} + +/* -------------------------------------------------------------------------------- + * + */ + +static void +gtk_entry_buffer_real_inserted_text (GtkEntryBuffer *buffer, + guint position, + const gchar *chars, + guint n_chars) +{ + g_object_notify (G_OBJECT (buffer), "text"); + g_object_notify (G_OBJECT (buffer), "length"); +} + +static void +gtk_entry_buffer_real_deleted_text (GtkEntryBuffer *buffer, + guint position, + guint n_chars) +{ + g_object_notify (G_OBJECT (buffer), "text"); + g_object_notify (G_OBJECT (buffer), "length"); +} + +/* -------------------------------------------------------------------------------- + * + */ + +static void +gtk_entry_buffer_init (GtkEntryBuffer *buffer) +{ + GtkEntryBufferPrivate *pv; + + pv = buffer->priv = G_TYPE_INSTANCE_GET_PRIVATE (buffer, GTK_TYPE_ENTRY_BUFFER, GtkEntryBufferPrivate); + + pv->normal_text = NULL; + pv->normal_text_chars = 0; + pv->normal_text_bytes = 0; + pv->normal_text_size = 0; +} + +static void +gtk_entry_buffer_finalize (GObject *obj) +{ + GtkEntryBuffer *buffer = GTK_ENTRY_BUFFER (obj); + GtkEntryBufferPrivate *pv = buffer->priv; + + if (pv->normal_text) + { + trash_area (pv->normal_text, pv->normal_text_size); + g_free (pv->normal_text); + pv->normal_text = NULL; + pv->normal_text_bytes = pv->normal_text_size = 0; + pv->normal_text_chars = 0; + } + + G_OBJECT_CLASS (gtk_entry_buffer_parent_class)->finalize (obj); +} + +static void +gtk_entry_buffer_set_property (GObject *obj, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GtkEntryBuffer *buffer = GTK_ENTRY_BUFFER (obj); + + switch (prop_id) + { + case PROP_TEXT: + gtk_entry_buffer_set_text (buffer, g_value_get_string (value), -1); + break; + case PROP_MAX_LENGTH: + gtk_entry_buffer_set_max_length (buffer, g_value_get_int (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); + break; + } +} + +static void +gtk_entry_buffer_get_property (GObject *obj, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GtkEntryBuffer *buffer = GTK_ENTRY_BUFFER (obj); + + switch (prop_id) + { + case PROP_TEXT: + g_value_set_string (value, gtk_entry_buffer_get_text (buffer)); + break; + case PROP_LENGTH: + g_value_set_uint (value, gtk_entry_buffer_get_length (buffer)); + break; + case PROP_MAX_LENGTH: + g_value_set_int (value, gtk_entry_buffer_get_max_length (buffer)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); + break; + } +} + +static void +gtk_entry_buffer_class_init (GtkEntryBufferClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = gtk_entry_buffer_finalize; + gobject_class->set_property = gtk_entry_buffer_set_property; + gobject_class->get_property = gtk_entry_buffer_get_property; + + klass->get_text = gtk_entry_buffer_normal_get_text; + klass->get_length = gtk_entry_buffer_normal_get_length; + klass->insert_text = gtk_entry_buffer_normal_insert_text; + klass->delete_text = gtk_entry_buffer_normal_delete_text; + + klass->inserted_text = gtk_entry_buffer_real_inserted_text; + klass->deleted_text = gtk_entry_buffer_real_deleted_text; + + g_type_class_add_private (gobject_class, sizeof (GtkEntryBufferPrivate)); + + /** + * GtkEntryBuffer:text: + * + * The contents of the buffer. + * + * Since: 2.18 + */ + g_object_class_install_property (gobject_class, + PROP_TEXT, + g_param_spec_string ("text", + P_("Text"), + P_("The contents of the buffer"), + "", + GTK_PARAM_READWRITE)); + + /** + * GtkEntryBuffer:length: + * + * The length (in characters) of the text in buffer. + * + * Since: 2.18 + */ + g_object_class_install_property (gobject_class, + PROP_LENGTH, + g_param_spec_uint ("length", + P_("Text length"), + P_("Length of the text currently in the buffer"), + 0, GTK_ENTRY_BUFFER_MAX_SIZE, 0, + GTK_PARAM_READABLE)); + + /** + * GtkEntryBuffer:max-length: + * + * The maximum length (in characters) of the text in the buffer. + * + * Since: 2.18 + */ + g_object_class_install_property (gobject_class, + PROP_MAX_LENGTH, + g_param_spec_int ("max-length", + P_("Maximum length"), + P_("Maximum number of characters for this entry. Zero if no maximum"), + 0, GTK_ENTRY_BUFFER_MAX_SIZE, 0, + GTK_PARAM_READWRITE)); + + /** + * GtkEntry::inserted-text: + * @buffer: a #GtkEntryBuffer + * @position: the position the text was inserted at. + * @chars: The text that was inserted. + * @n_chars: The number of characters that were inserted. + * + * This signal is emitted after text is inserted into the buffer. + * + * Since: 2.18 + */ + signals[INSERTED_TEXT] = g_signal_new (I_("inserted-text"), + GTK_TYPE_ENTRY_BUFFER, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GtkEntryBufferClass, inserted_text), + NULL, NULL, + _gtk_marshal_VOID__UINT_STRING_UINT, + G_TYPE_NONE, 3, + G_TYPE_UINT, + G_TYPE_STRING, + G_TYPE_UINT); + + /** + * GtkEntry::deleted-text: + * @buffer: a #GtkEntryBuffer + * @position: the position the text was deleted at. + * @n_chars: The number of characters that were deleted. + * + * This signal is emitted after text is deleted from the buffer. + * + * Since: 2.18 + */ + signals[DELETED_TEXT] = g_signal_new (I_("deleted-text"), + GTK_TYPE_ENTRY_BUFFER, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GtkEntryBufferClass, deleted_text), + NULL, NULL, + _gtk_marshal_VOID__UINT_UINT, + G_TYPE_NONE, 2, + G_TYPE_UINT, + G_TYPE_UINT); +} + +/* -------------------------------------------------------------------------------- + * + */ + +/** + * gtk_entry_buffer_new: + * @initial_chars: initial buffer text, or %NULL + * @n_initial_chars: number of characters in @initial_chars, or -1 + * + * Create a new GtkEntryBuffer object. + * + * Optionally, specify initial text to set in the buffer. + * + * Return value: A new GtkEntryBuffer object. + * + * Since: 2.18 + **/ +GtkEntryBuffer* +gtk_entry_buffer_new (const gchar *initial_chars, + gint n_initial_chars) +{ + GtkEntryBuffer *buffer = g_object_new (GTK_TYPE_ENTRY_BUFFER, NULL); + if (initial_chars) + gtk_entry_buffer_set_text (buffer, initial_chars, n_initial_chars); + return buffer; +} + +/** + * gtk_entry_buffer_get_length: + * @buffer: a #GtkEntryBuffer + * + * Retrieves the length in characters of the buffer. + * + * Return value: The number of characters in the buffer. + * + * Since: 2.18 + **/ +guint +gtk_entry_buffer_get_length (GtkEntryBuffer *buffer) +{ + GtkEntryBufferClass *klass; + + g_return_val_if_fail (GTK_IS_ENTRY_BUFFER (buffer), 0); + + klass = GTK_ENTRY_BUFFER_GET_CLASS (buffer); + g_return_val_if_fail (klass->get_length != NULL, 0); + + return (*klass->get_length) (buffer); +} + +/** + * gtk_entry_buffer_get_bytes: + * @buffer: a #GtkEntryBuffer + * + * Retrieves the length in bytes of the buffer. + * See gtk_entry_buffer_get_length(). + * + * Return value: The byte length of the buffer. + * + * Since: 2.18 + **/ +gsize +gtk_entry_buffer_get_bytes (GtkEntryBuffer *buffer) +{ + GtkEntryBufferClass *klass; + gsize bytes = 0; + + g_return_val_if_fail (GTK_IS_ENTRY_BUFFER (buffer), 0); + + klass = GTK_ENTRY_BUFFER_GET_CLASS (buffer); + g_return_val_if_fail (klass->get_text != NULL, 0); + + (*klass->get_text) (buffer, &bytes); + return bytes; +} + +/** + * gtk_entry_buffer_get_text: + * @buffer: a #GtkEntryBuffer + * + * Retrieves the contents of the buffer. + * + * The memory pointer returned by this call will not change + * unless this object emits a signal, or is finalized. + * + * Return value: a pointer to the contents of the widget as a + * string. This string points to internally allocated + * storage in the buffer and must not be freed, modified or + * stored. + * + * Since: 2.18 + **/ +G_CONST_RETURN gchar* +gtk_entry_buffer_get_text (GtkEntryBuffer *buffer) +{ + GtkEntryBufferClass *klass; + + g_return_val_if_fail (GTK_IS_ENTRY_BUFFER (buffer), NULL); + + klass = GTK_ENTRY_BUFFER_GET_CLASS (buffer); + g_return_val_if_fail (klass->get_text != NULL, NULL); + + return (*klass->get_text) (buffer, NULL); +} + +/** + * gtk_entry_buffer_set_text: + * @buffer: a #GtkEntryBuffer + * @chars: the new text + * @n_chars: the number of characters in @text, or -1 + * + * Sets the text in the buffer. + * + * This is roughly equivalent to calling gtk_entry_buffer_delete_text() + * and gtk_entry_buffer_insert_text(). + * + * Note that @n_chars is in characters, not in bytes. + * + * Since: 2.18 + **/ +void +gtk_entry_buffer_set_text (GtkEntryBuffer *buffer, + const gchar *chars, + gint n_chars) +{ + g_return_if_fail (GTK_IS_ENTRY_BUFFER (buffer)); + g_return_if_fail (chars != NULL); + + g_object_freeze_notify (G_OBJECT (buffer)); + gtk_entry_buffer_delete_text (buffer, 0, -1); + gtk_entry_buffer_insert_text (buffer, 0, chars, n_chars); + g_object_thaw_notify (G_OBJECT (buffer)); +} + +/** + * gtk_entry_buffer_set_max_length: + * @buffer: a #GtkEntryBuffer + * @max_length: the maximum length of the entry buffer, or 0 for no maximum. + * (other than the maximum length of entries.) The value passed in will + * be clamped to the range 0-65536. + * + * Sets the maximum allowed length of the contents of the buffer. If + * the current contents are longer than the given length, then they + * will be truncated to fit. + * + * Since: 2.18 + **/ +void +gtk_entry_buffer_set_max_length (GtkEntryBuffer *buffer, + gint max_length) +{ + g_return_if_fail (GTK_IS_ENTRY_BUFFER (buffer)); + + max_length = CLAMP (max_length, 0, GTK_ENTRY_BUFFER_MAX_SIZE); + + if (max_length > 0 && gtk_entry_buffer_get_length (buffer) > max_length) + gtk_entry_buffer_delete_text (buffer, max_length, -1); + + buffer->priv->max_length = max_length; + g_object_notify (G_OBJECT (buffer), "max-length"); +} + +/** + * gtk_entry_buffer_get_max_length: + * @buffer: a #GtkEntryBuffer + * + * Retrieves the maximum allowed length of the text in + * @buffer. See gtk_entry_buffer_set_max_length(). + * + * Return value: the maximum allowed number of characters + * in #GtkEntryBuffer, or 0 if there is no maximum. + * + * Since: 2.18 + */ +gint +gtk_entry_buffer_get_max_length (GtkEntryBuffer *buffer) +{ + g_return_val_if_fail (GTK_IS_ENTRY_BUFFER (buffer), 0); + return buffer->priv->max_length; +} + +/** + * gtk_entry_buffer_insert_text: + * @buffer: a #GtkEntryBuffer + * @position: the position at which to insert text. + * @chars: the text to insert into the buffer. + * @n_chars: the length of the text in characters, or -1 + * + * Inserts @n_chars characters of @chars into the contents of the + * buffer, at position @position. + * + * If @n_chars is negative, then characters from chars will be inserted + * until a null-terminator is found. If @position or @n_chars are out of + * bounds, or the maximum buffer text length is exceeded, then they are + * coerced to sane values. + * + * Note that the position and length are in characters, not in bytes. + * + * Returns: The number of characters actually inserted. + * + * Since: 2.18 + */ +guint +gtk_entry_buffer_insert_text (GtkEntryBuffer *buffer, + guint position, + const gchar *chars, + gint n_chars) +{ + GtkEntryBufferClass *klass; + GtkEntryBufferPrivate *pv; + guint length; + + g_return_val_if_fail (GTK_IS_ENTRY_BUFFER (buffer), 0); + + length = gtk_entry_buffer_get_length (buffer); + pv = buffer->priv; + + if (n_chars < 0) + n_chars = g_utf8_strlen (chars, -1); + + /* Bring position into bounds */ + if (position > length) + position = length; + + /* Make sure not entering too much data */ + if (pv->max_length > 0) + { + if (length >= pv->max_length) + n_chars = 0; + else if (length + n_chars > pv->max_length) + n_chars -= (length + n_chars) - pv->max_length; + } + + klass = GTK_ENTRY_BUFFER_GET_CLASS (buffer); + g_return_val_if_fail (klass->insert_text != NULL, 0); + + return (*klass->insert_text) (buffer, position, chars, n_chars); +} + +/** + * gtk_entry_buffer_delete_text: + * @buffer: a #GtkEntryBuffer + * @position: position at which to delete text + * @n_chars: number of characters to delete + * + * Deletes a sequence of characters from the buffer. @n_chars characters are + * deleted starting at @position. If @n_chars is negative, then all characters + * until the end of the text are deleted. + * + * If @position or @n_chars are out of bounds, then they are coerced to sane + * values. + * + * Note that the positions are specified in characters, not bytes. + * + * Returns: The number of characters deleted. + * + * Since: 2.18 + */ +guint +gtk_entry_buffer_delete_text (GtkEntryBuffer *buffer, + guint position, + gint n_chars) +{ + GtkEntryBufferClass *klass; + guint length; + + g_return_val_if_fail (GTK_IS_ENTRY_BUFFER (buffer), 0); + + length = gtk_entry_buffer_get_length (buffer); + if (n_chars < 0) + n_chars = length; + if (position > length) + position = length; + if (position + n_chars > length) + n_chars = length - position; + + klass = GTK_ENTRY_BUFFER_GET_CLASS (buffer); + g_return_val_if_fail (klass->delete_text != NULL, 0); + + return (*klass->delete_text) (buffer, position, n_chars); +} + +/** + * gtk_entry_buffer_emit_inserted_text: + * @buffer: a #GtkEntryBuffer + * @position: position at which text was inserted + * @chars: text that was inserted + * @n_chars: number of characters inserted + * + * Used when subclassing #GtkEntryBuffer + * + * Since: 2.18 + */ +void +gtk_entry_buffer_emit_inserted_text (GtkEntryBuffer *buffer, + guint position, + const gchar *chars, + guint n_chars) +{ + g_return_if_fail (GTK_IS_ENTRY_BUFFER (buffer)); + g_signal_emit (buffer, signals[INSERTED_TEXT], 0, position, chars, n_chars); +} + +/** + * gtk_entry_buffer_emit_deleted_text: + * @buffer: a #GtkEntryBuffer + * @position: position at which text was deleted + * @n_chars: number of characters deleted + * + * Used when subclassing #GtkEntryBuffer + * + * Since: 2.18 + */ +void +gtk_entry_buffer_emit_deleted_text (GtkEntryBuffer *buffer, + guint position, + guint n_chars) +{ + g_return_if_fail (GTK_IS_ENTRY_BUFFER (buffer)); + g_signal_emit (buffer, signals[DELETED_TEXT], 0, position, n_chars); +} + +#define __GTK_ENTRY_BUFFER_C__ +#include "gtkaliasdef.c" diff --git a/gtk/gtkentrybuffer.h b/gtk/gtkentrybuffer.h new file mode 100644 index 0000000000..20556cb9e8 --- /dev/null +++ b/gtk/gtkentrybuffer.h @@ -0,0 +1,133 @@ +/* gtkentrybuffer.h + * Copyright (C) 2009 Stefan Walter + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#if defined(GTK_DISABLE_SINGLE_INCLUDES) && !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __GTK_ENTRY_BUFFER_H__ +#define __GTK_ENTRY_BUFFER_H__ + +#include + +G_BEGIN_DECLS + +/* Maximum size of text buffer, in bytes */ +#define GTK_ENTRY_BUFFER_MAX_SIZE G_MAXUSHORT + +#define GTK_TYPE_ENTRY_BUFFER (gtk_entry_buffer_get_type ()) +#define GTK_ENTRY_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_ENTRY_BUFFER, GtkEntryBuffer)) +#define GTK_ENTRY_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_ENTRY_BUFFER, GtkEntryBufferClass)) +#define GTK_IS_ENTRY_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_ENTRY_BUFFER)) +#define GTK_IS_ENTRY_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_ENTRY_BUFFER)) +#define GTK_ENTRY_BUFFER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_ENTRY_BUFFER, GtkEntryBufferClass)) + +typedef struct _GtkEntryBuffer GtkEntryBuffer; +typedef struct _GtkEntryBufferClass GtkEntryBufferClass; +typedef struct _GtkEntryBufferPrivate GtkEntryBufferPrivate; + +struct _GtkEntryBuffer +{ + GObject parent_instance; + + /*< private >*/ + GtkEntryBufferPrivate *priv; +}; + +struct _GtkEntryBufferClass +{ + GObjectClass parent_class; + + /* Signals */ + + void (*inserted_text) (GtkEntryBuffer *buffer, + guint position, + const gchar *chars, + guint n_chars); + + void (*deleted_text) (GtkEntryBuffer *buffer, + guint position, + guint n_chars); + + /* Virtual Methods */ + + const gchar* (*get_text) (GtkEntryBuffer *buffer, + gsize *n_bytes); + + guint (*get_length) (GtkEntryBuffer *buffer); + + guint (*insert_text) (GtkEntryBuffer *buffer, + guint position, + const gchar *chars, + guint n_chars); + + guint (*delete_text) (GtkEntryBuffer *buffer, + guint position, + guint n_chars); + + /* Padding for future expansion */ + void (*_gtk_reserved0) (void); + void (*_gtk_reserved1) (void); + void (*_gtk_reserved2) (void); + void (*_gtk_reserved3) (void); + void (*_gtk_reserved4) (void); + void (*_gtk_reserved5) (void); +}; + +GType gtk_entry_buffer_get_type (void) G_GNUC_CONST; + +GtkEntryBuffer* gtk_entry_buffer_new (const gchar *initial_chars, + gint n_initial_chars); + +gsize gtk_entry_buffer_get_bytes (GtkEntryBuffer *buffer); + +guint gtk_entry_buffer_get_length (GtkEntryBuffer *buffer); + +G_CONST_RETURN gchar* gtk_entry_buffer_get_text (GtkEntryBuffer *buffer); + +void gtk_entry_buffer_set_text (GtkEntryBuffer *buffer, + const gchar *chars, + gint n_chars); + +void gtk_entry_buffer_set_max_length (GtkEntryBuffer *buffer, + gint max_length); + +gint gtk_entry_buffer_get_max_length (GtkEntryBuffer *buffer); + +guint gtk_entry_buffer_insert_text (GtkEntryBuffer *buffer, + guint position, + const gchar *chars, + gint n_chars); + +guint gtk_entry_buffer_delete_text (GtkEntryBuffer *buffer, + guint position, + gint n_chars); + +void gtk_entry_buffer_emit_inserted_text (GtkEntryBuffer *buffer, + guint position, + const gchar *chars, + guint n_chars); + +void gtk_entry_buffer_emit_deleted_text (GtkEntryBuffer *buffer, + guint position, + guint n_chars); + +G_END_DECLS + +#endif /* __GTK_ENTRY_BUFFER_H__ */ diff --git a/gtk/gtkfilechooser.c b/gtk/gtkfilechooser.c index f113bea1f0..6c7de57225 100644 --- a/gtk/gtkfilechooser.c +++ b/gtk/gtkfilechooser.c @@ -269,6 +269,22 @@ gtk_file_chooser_class_init (gpointer g_iface) "if necessary."), FALSE, GTK_PARAM_READWRITE)); + + /** + * GtkFileChooser:create-folders: + * + * Whether a file chooser not in %GTK_FILE_CHOOSER_ACTION_OPEN mode + * will offer the user to create new folders. + * + * Since: 2.18 + */ + g_object_interface_install_property (g_iface, + g_param_spec_boolean ("create-folders", + P_("Allow folders creation"), + P_("Whether a file chooser not in open mode " + "will offer the user to create new folders."), + TRUE, + GTK_PARAM_READWRITE)); } /** @@ -423,6 +439,49 @@ gtk_file_chooser_get_select_multiple (GtkFileChooser *chooser) return select_multiple; } +/** + * gtk_file_chooser_set_create_folders: + * @chooser: a #GtkFileChooser + * @create_folders: %TRUE if the New Folder button should be displayed + * + * Sets whether file choser will offer to create new folders. + * This is only relevant if the action is not set to be + * GTK_FILE_CHOOSER_ACTION_OPEN. + * + * Since: 2.18 + **/ +void +gtk_file_chooser_set_create_folders (GtkFileChooser *chooser, + gboolean create_folders) +{ + g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser)); + + g_object_set (chooser, "create-folders", create_folders, NULL); +} + +/** + * gtk_file_chooser_get_create_folders: + * @chooser: a #GtkFileChooser + * + * Gets whether file choser will offer to create new folders. + * See gtk_file_chooser_set_create_folders(). + * + * Return value: %TRUE if the New Folder button should be displayed. + * + * Since: 2.18 + **/ +gboolean +gtk_file_chooser_get_create_folders (GtkFileChooser *chooser) +{ + gboolean create_folders; + + g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), FALSE); + + g_object_get (chooser, "create-folders", &create_folders, NULL); + + return create_folders; +} + /** * gtk_file_chooser_get_filename: * @chooser: a #GtkFileChooser @@ -1180,7 +1239,8 @@ gtk_file_chooser_set_file (GtkFileChooser *chooser, * If the file chooser is in folder mode, this function returns the selected * folder. * - * Returns: a selected #GFile + * Returns: a selected #GFile. You own the returned file; use + * g_object_unref() to release it. * * Since: 2.14 **/ diff --git a/gtk/gtkfilechooser.h b/gtk/gtkfilechooser.h index b7983a9660..0772690bd2 100644 --- a/gtk/gtkfilechooser.h +++ b/gtk/gtkfilechooser.h @@ -85,6 +85,10 @@ void gtk_file_chooser_set_do_overwrite_confirmation (GtkFileChoo gboolean do_overwrite_confirmation); gboolean gtk_file_chooser_get_do_overwrite_confirmation (GtkFileChooser *chooser); +void gtk_file_chooser_set_create_folders (GtkFileChooser *chooser, + gboolean create_folders); +gboolean gtk_file_chooser_get_create_folders (GtkFileChooser *chooser); + /* Suggested name for the Save-type actions */ void gtk_file_chooser_set_current_name (GtkFileChooser *chooser, diff --git a/gtk/gtkfilechooserbutton.c b/gtk/gtkfilechooserbutton.c index 3b95adeeda..4319bb0298 100644 --- a/gtk/gtkfilechooserbutton.c +++ b/gtk/gtkfilechooserbutton.c @@ -810,6 +810,7 @@ gtk_file_chooser_button_set_property (GObject *object, case GTK_FILE_CHOOSER_PROP_EXTRA_WIDGET: case GTK_FILE_CHOOSER_PROP_SHOW_HIDDEN: case GTK_FILE_CHOOSER_PROP_DO_OVERWRITE_CONFIRMATION: + case GTK_FILE_CHOOSER_PROP_CREATE_FOLDERS: g_object_set_property (G_OBJECT (priv->dialog), pspec->name, value); break; diff --git a/gtk/gtkfilechooserdefault.c b/gtk/gtkfilechooserdefault.c index 34bc6f7821..3ad05f0f83 100644 --- a/gtk/gtkfilechooserdefault.c +++ b/gtk/gtkfilechooserdefault.c @@ -723,6 +723,7 @@ _gtk_file_chooser_default_init (GtkFileChooserDefault *impl) impl->sort_column = MODEL_COL_NAME; impl->sort_order = GTK_SORT_ASCENDING; impl->recent_manager = gtk_recent_manager_get_default (); + impl->create_folders = TRUE; gtk_box_set_spacing (GTK_BOX (impl), 12); @@ -2856,24 +2857,27 @@ bookmarks_check_remove_sensitivity (GtkFileChooserDefault *impl) GtkTreeIter iter; gboolean removable = FALSE; gchar *name = NULL; + gchar *tip; if (shortcuts_get_selected (impl, &iter)) - gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter, - SHORTCUTS_COL_REMOVABLE, &removable, - SHORTCUTS_COL_NAME, &name, - -1); - - gtk_widget_set_sensitive (impl->browse_shortcuts_remove_button, removable); - - if (removable) { - gchar *tip; + gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter, + SHORTCUTS_COL_REMOVABLE, &removable, + SHORTCUTS_COL_NAME, &name, + -1); + gtk_widget_set_sensitive (impl->browse_shortcuts_remove_button, removable); + + if (removable) + tip = g_strdup_printf (_("Remove the bookmark '%s'"), name); + else + tip = g_strdup_printf (_("Bookmark '%s' cannot be removed"), name); - tip = g_strdup_printf (_("Remove the bookmark '%s'"), name); gtk_widget_set_tooltip_text (impl->browse_shortcuts_remove_button, tip); g_free (tip); } - + else + gtk_widget_set_tooltip_text (impl->browse_shortcuts_remove_button, + _("Remove the selected bookmark")); g_free (name); } @@ -3498,26 +3502,34 @@ shortcuts_row_separator_func (GtkTreeModel *model, return shortcut_type == SHORTCUT_TYPE_SEPARATOR; } -/* Since GtkTreeView has a keybinding attached to '/', we need to catch - * keypresses before the TreeView gets them. - */ static gboolean -tree_view_keybinding_cb (GtkWidget *tree_view, - GdkEventKey *event, - GtkFileChooserDefault *impl) +shortcuts_key_press_event_after_cb (GtkWidget *tree_view, + GdkEventKey *event, + GtkFileChooserDefault *impl) { - if ((event->keyval == GDK_slash - || event->keyval == GDK_KP_Divide -#ifdef G_OS_UNIX - || event->keyval == GDK_asciitilde -#endif - ) && ! (event->state & (~GDK_SHIFT_MASK & gtk_accelerator_get_default_mod_mask ()))) - { - location_popup_handler (impl, event->string); - return TRUE; - } + GtkWidget *entry; - return FALSE; + /* don't screw up focus switching with Tab */ + if (event->keyval == GDK_Tab + || event->keyval == GDK_KP_Tab + || event->keyval == GDK_ISO_Left_Tab + || event->length < 1) + return FALSE; + + if (impl->location_entry) + entry = impl->location_entry; + else if (impl->search_entry) + entry = impl->search_entry; + else + entry = NULL; + + if (entry) + { + gtk_widget_grab_focus (entry); + return gtk_widget_event (entry, (GdkEvent *) event); + } + else + return FALSE; } /* Callback used when the file list's popup menu is detached */ @@ -3732,11 +3744,28 @@ shortcuts_list_create (GtkFileChooserDefault *impl) /* Tree */ impl->browse_shortcuts_tree_view = gtk_tree_view_new (); + gtk_tree_view_set_enable_search (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view), FALSE); #ifdef PROFILE_FILE_CHOOSER g_object_set_data (G_OBJECT (impl->browse_shortcuts_tree_view), "fmq-name", "shortcuts"); #endif - g_signal_connect (impl->browse_shortcuts_tree_view, "key-press-event", - G_CALLBACK (tree_view_keybinding_cb), impl); + + /* Connect "after" to key-press-event on the shortcuts pane. We want this action to be possible: + * + * 1. user brings up a SAVE dialog + * 2. user clicks on a shortcut in the shortcuts pane + * 3. user starts typing a filename + * + * Normally, the user's typing would be ignored, as the shortcuts treeview doesn't + * support interactive search. However, we'd rather focus the location entry + * so that the user can type *there*. + * + * To preserve keyboard navigation in the shortcuts pane, we don't focus the + * filename entry if one clicks on a shortcut; rather, we focus the entry only + * if the user starts typing while the focus is in the shortcuts pane. + */ + g_signal_connect_after (impl->browse_shortcuts_tree_view, "key-press-event", + G_CALLBACK (shortcuts_key_press_event_after_cb), impl); + g_signal_connect (impl->browse_shortcuts_tree_view, "popup-menu", G_CALLBACK (shortcuts_popup_menu_cb), impl); g_signal_connect (impl->browse_shortcuts_tree_view, "button-press-event", @@ -3879,14 +3908,28 @@ shortcuts_pane_create (GtkFileChooserDefault *impl, return vbox; } +static gboolean +key_is_left_or_right (GdkEventKey *event) +{ + guint modifiers; + + modifiers = gtk_accelerator_get_default_mod_mask (); + + return ((event->keyval == GDK_Right + || event->keyval == GDK_KP_Right + || event->keyval == GDK_Left + || event->keyval == GDK_KP_Left) + && (event->state & modifiers) == 0); +} + /* Handles key press events on the file list, so that we can trap Enter to * activate the default button on our own. Also, checks to see if '/' has been * pressed. See comment by tree_view_keybinding_cb() for more details. */ static gboolean -trap_activate_cb (GtkWidget *widget, - GdkEventKey *event, - gpointer data) +browse_files_key_press_event_cb (GtkWidget *widget, + GdkEventKey *event, + gpointer data) { GtkFileChooserDefault *impl; int modifiers; @@ -3906,6 +3949,12 @@ trap_activate_cb (GtkWidget *widget, return TRUE; } + if (key_is_left_or_right (event)) + { + gtk_widget_grab_focus (impl->browse_shortcuts_tree_view); + return TRUE; + } + if ((event->keyval == GDK_Return || event->keyval == GDK_ISO_Enter || event->keyval == GDK_KP_Enter @@ -4411,7 +4460,7 @@ create_file_list (GtkFileChooserDefault *impl) g_signal_connect (impl->browse_files_tree_view, "row-activated", G_CALLBACK (list_row_activated), impl); g_signal_connect (impl->browse_files_tree_view, "key-press-event", - G_CALLBACK (trap_activate_cb), impl); + G_CALLBACK (browse_files_key_press_event_cb), impl); g_signal_connect (impl->browse_files_tree_view, "popup-menu", G_CALLBACK (list_popup_menu_cb), impl); g_signal_connect (impl->browse_files_tree_view, "button-press-event", @@ -4586,6 +4635,39 @@ save_folder_combo_changed_cb (GtkComboBox *combo, } } +static void +save_folder_update_tooltip (GtkComboBox *combo, + GtkFileChooserDefault *impl) +{ + GtkTreeIter iter; + gchar *tooltip; + + tooltip = NULL; + + if (gtk_combo_box_get_active_iter (combo, &iter)) + { + GtkTreeIter child_iter; + gpointer col_data; + ShortcutType shortcut_type; + + gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (impl->shortcuts_combo_filter_model), + &child_iter, + &iter); + gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &child_iter, + SHORTCUTS_COL_DATA, &col_data, + SHORTCUTS_COL_TYPE, &shortcut_type, + -1); + + if (shortcut_type == SHORTCUT_TYPE_FILE) + tooltip = g_file_get_parse_name (G_FILE (col_data)); + } + + gtk_widget_set_tooltip_text (GTK_WIDGET (combo), tooltip); + gtk_widget_set_has_tooltip (GTK_WIDGET (combo), + gtk_widget_get_sensitive (GTK_WIDGET (combo))); + g_free (tooltip); +} + /* Filter function used to filter out the Search item and its separator. * Used for the "Save in folder" combo box, so that these items do not appear in it. */ @@ -4677,6 +4759,8 @@ save_folder_combo_create (GtkFileChooserDefault *impl) g_signal_connect (combo, "changed", G_CALLBACK (save_folder_combo_changed_cb), impl); + g_signal_connect (combo, "changed", + G_CALLBACK (save_folder_update_tooltip), impl); return combo; } @@ -5285,12 +5369,14 @@ update_appearance (GtkFileChooserDefault *impl) { gtk_widget_set_sensitive (impl->save_folder_label, FALSE); gtk_widget_set_sensitive (impl->save_folder_combo, FALSE); + gtk_widget_set_has_tooltip (impl->save_folder_combo, FALSE); gtk_widget_show (impl->browse_widgets); } else { gtk_widget_set_sensitive (impl->save_folder_label, TRUE); gtk_widget_set_sensitive (impl->save_folder_combo, TRUE); + gtk_widget_set_has_tooltip (impl->save_folder_combo, TRUE); gtk_widget_hide (impl->browse_widgets); } @@ -5313,7 +5399,7 @@ update_appearance (GtkFileChooserDefault *impl) if (impl->location_entry) _gtk_file_chooser_entry_set_action (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), impl->action); - if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN) + if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN || !impl->create_folders) gtk_widget_hide (impl->browse_new_folder_button); else gtk_widget_show (impl->browse_new_folder_button); @@ -5429,6 +5515,14 @@ gtk_file_chooser_default_set_property (GObject *object, } break; + case GTK_FILE_CHOOSER_PROP_CREATE_FOLDERS: + { + gboolean create_folders = g_value_get_boolean (value); + impl->create_folders = create_folders; + update_appearance (impl); + } + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -5485,6 +5579,10 @@ gtk_file_chooser_default_get_property (GObject *object, g_value_set_boolean (value, impl->do_overwrite_confirmation); break; + case GTK_FILE_CHOOSER_PROP_CREATE_FOLDERS: + g_value_set_boolean (value, impl->create_folders); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -8787,7 +8885,7 @@ search_switch_to_browse_mode (GtkFileChooserDefault *impl) impl->search_entry = NULL; gtk_widget_show (impl->browse_path_bar); - if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN) + if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN || !impl->create_folders) gtk_widget_hide (impl->browse_new_folder_button); else gtk_widget_show (impl->browse_new_folder_button); @@ -8909,6 +9007,7 @@ search_setup_widgets (GtkFileChooserDefault *impl) { GtkWidget *label; GtkWidget *image; + gchar *tmp; impl->search_hbox = gtk_hbox_new (FALSE, 12); @@ -8921,8 +9020,10 @@ search_setup_widgets (GtkFileChooserDefault *impl) /* Label */ label = gtk_label_new (NULL); - gtk_label_set_markup_with_mnemonic (GTK_LABEL (label), _("_Search:")); + tmp = g_strdup_printf ("%s", _("Search:")); + gtk_label_set_markup_with_mnemonic (GTK_LABEL (label), tmp); gtk_box_pack_start (GTK_BOX (impl->search_hbox), label, FALSE, FALSE, 0); + g_free (tmp); /* Entry */ @@ -9080,7 +9181,7 @@ recent_switch_to_browse_mode (GtkFileChooserDefault *impl) impl->recent_hbox = NULL; gtk_widget_show (impl->browse_path_bar); - if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN) + if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN || !impl->create_folders) gtk_widget_hide (impl->browse_new_folder_button); else gtk_widget_show (impl->browse_new_folder_button); @@ -9336,6 +9437,7 @@ recent_hide_entry (GtkFileChooserDefault *impl) { GtkWidget *label; GtkWidget *image; + gchar *tmp; impl->recent_hbox = gtk_hbox_new (FALSE, 12); @@ -9346,8 +9448,10 @@ recent_hide_entry (GtkFileChooserDefault *impl) /* Label */ label = gtk_label_new (NULL); - gtk_label_set_markup_with_mnemonic (GTK_LABEL (label), _("Recently Used")); + tmp = g_strdup_printf ("%s", _("Recently Used")); + gtk_label_set_markup_with_mnemonic (GTK_LABEL (label), tmp); gtk_box_pack_start (GTK_BOX (impl->recent_hbox), label, FALSE, FALSE, 0); + g_free (tmp); gtk_widget_hide (impl->browse_path_bar); gtk_widget_hide (impl->browse_new_folder_button); @@ -9416,11 +9520,15 @@ set_current_filter (GtkFileChooserDefault *impl, if (impl->browse_files_model) install_list_model_filter (impl); - if (impl->search_model) + if (impl->operation_mode == OPERATION_MODE_SEARCH + && impl->search_model) _gtk_file_system_model_set_filter (impl->search_model, filter); - if (impl->recent_model) - _gtk_file_system_model_set_filter (impl->recent_model, filter); + /* we want to have all the matching results, and not just a + * filter of the previous model + */ + if (impl->operation_mode == OPERATION_MODE_RECENT) + recent_start_loading (impl); g_object_notify (G_OBJECT (impl), "filter"); } @@ -9747,6 +9855,12 @@ shortcuts_key_press_event_cb (GtkWidget *widget, modifiers = gtk_accelerator_get_default_mod_mask (); + if (key_is_left_or_right (event)) + { + gtk_widget_grab_focus (impl->browse_files_tree_view); + return TRUE; + } + if ((event->keyval == GDK_BackSpace || event->keyval == GDK_Delete || event->keyval == GDK_KP_Delete) diff --git a/gtk/gtkfilechooserdialog.c b/gtk/gtkfilechooserdialog.c index 0868691e22..2dd3737154 100644 --- a/gtk/gtkfilechooserdialog.c +++ b/gtk/gtkfilechooserdialog.c @@ -224,6 +224,11 @@ file_chooser_widget_response_requested (GtkWidget *widget, { GList *children, *l; + dialog->priv->response_requested = TRUE; + + if (gtk_window_activate_default (GTK_WINDOW (dialog))) + return; + /* There probably isn't a default widget, so make things easier for the * programmer by looking for a reasonable button on our own. */ @@ -239,12 +244,14 @@ file_chooser_widget_response_requested (GtkWidget *widget, response_id = gtk_dialog_get_response_for_widget (GTK_DIALOG (dialog), widget); if (is_stock_accept_response_id (response_id)) { - dialog->priv->response_requested = TRUE; gtk_widget_activate (widget); /* Should we gtk_dialog_response (dialog, response_id) instead? */ break; } } + if (l == NULL) + dialog->priv->response_requested = FALSE; + g_list_free (children); } diff --git a/gtk/gtkfilechooserprivate.h b/gtk/gtkfilechooserprivate.h index ede984edf7..9f02b42e67 100644 --- a/gtk/gtkfilechooserprivate.h +++ b/gtk/gtkfilechooserprivate.h @@ -301,6 +301,7 @@ struct _GtkFileChooserDefault guint has_search : 1; guint has_recent : 1; guint show_size_column : 1; + guint create_folders : 1; #if 0 guint shortcuts_drag_outside : 1; diff --git a/gtk/gtkfilechooserutils.c b/gtk/gtkfilechooserutils.c index 0eab525b3f..69c71d1116 100644 --- a/gtk/gtkfilechooserutils.c +++ b/gtk/gtkfilechooserutils.c @@ -117,6 +117,9 @@ _gtk_file_chooser_install_properties (GObjectClass *klass) g_object_class_override_property (klass, GTK_FILE_CHOOSER_PROP_DO_OVERWRITE_CONFIRMATION, "do-overwrite-confirmation"); + g_object_class_override_property (klass, + GTK_FILE_CHOOSER_PROP_CREATE_FOLDERS, + "create-folders"); } /** diff --git a/gtk/gtkfilechooserutils.h b/gtk/gtkfilechooserutils.h index c5c1aa75aa..a590cccd16 100644 --- a/gtk/gtkfilechooserutils.h +++ b/gtk/gtkfilechooserutils.h @@ -41,7 +41,8 @@ typedef enum { GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE, GTK_FILE_CHOOSER_PROP_SHOW_HIDDEN, GTK_FILE_CHOOSER_PROP_DO_OVERWRITE_CONFIRMATION, - GTK_FILE_CHOOSER_PROP_LAST = GTK_FILE_CHOOSER_PROP_DO_OVERWRITE_CONFIRMATION + GTK_FILE_CHOOSER_PROP_CREATE_FOLDERS, + GTK_FILE_CHOOSER_PROP_LAST = GTK_FILE_CHOOSER_PROP_CREATE_FOLDERS } GtkFileChooserProp; void _gtk_file_chooser_install_properties (GObjectClass *klass); diff --git a/gtk/gtkfilesel.c b/gtk/gtkfilesel.c index 0aa9f17d91..eca76ca910 100644 --- a/gtk/gtkfilesel.c +++ b/gtk/gtkfilesel.c @@ -1355,8 +1355,10 @@ gtk_file_selection_create_dir_confirmed (GtkWidget *widget, if (g_mkdir (sys_full_path, 0777) < 0) { + int errsv = errno; + buf = g_strdup_printf (_("Error creating folder '%s': %s"), - dirname, g_strerror (errno)); + dirname, g_strerror (errsv)); gtk_file_selection_fileop_error (fs, buf); } @@ -1484,8 +1486,10 @@ gtk_file_selection_delete_file_response (GtkDialog *dialog, if (g_unlink (sys_full_path) < 0) { + int errsv = errno; + buf = g_strdup_printf (_("Error deleting file '%s': %s"), - fs->fileop_file, g_strerror (errno)); + fs->fileop_file, g_strerror (errsv)); gtk_file_selection_fileop_error (fs, buf); } @@ -1602,9 +1606,11 @@ gtk_file_selection_rename_file_confirmed (GtkWidget *widget, if (g_rename (sys_old_filename, sys_new_filename) < 0) { + int errsv = errno; + buf = g_strdup_printf (_("Error renaming file \"%s\" to \"%s\": %s"), sys_old_filename, sys_new_filename, - g_strerror (errno)); + g_strerror (errsv)); gtk_file_selection_fileop_error (fs, buf); goto out2; } diff --git a/gtk/gtkhbbox.c b/gtk/gtkhbbox.c index d852daf0a2..50131d1ea1 100644 --- a/gtk/gtkhbbox.c +++ b/gtk/gtkhbbox.c @@ -21,7 +21,7 @@ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS * file for a list of people on the GTK+ Team. See the ChangeLog * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. */ #include "config.h" @@ -44,24 +44,20 @@ gtk_hbutton_box_class_init (GtkHButtonBoxClass *class) static void gtk_hbutton_box_init (GtkHButtonBox *hbutton_box) { - gtk_orientable_set_orientation (GTK_ORIENTABLE (hbutton_box), - GTK_ORIENTATION_HORIZONTAL); + gtk_orientable_set_orientation (GTK_ORIENTABLE (hbutton_box), + GTK_ORIENTATION_HORIZONTAL); } -GtkWidget* +GtkWidget * gtk_hbutton_box_new (void) { - GtkHButtonBox *hbutton_box; - - hbutton_box = g_object_new (GTK_TYPE_HBUTTON_BOX, NULL); - - return GTK_WIDGET (hbutton_box); + return g_object_new (GTK_TYPE_HBUTTON_BOX, NULL); } /* set default value for spacing */ -void +void gtk_hbutton_box_set_spacing_default (gint spacing) { default_spacing = spacing; @@ -70,7 +66,7 @@ gtk_hbutton_box_set_spacing_default (gint spacing) /* set default value for layout style */ -void +void gtk_hbutton_box_set_layout_default (GtkButtonBoxStyle layout) { g_return_if_fail (layout >= GTK_BUTTONBOX_DEFAULT_STYLE && @@ -81,7 +77,7 @@ gtk_hbutton_box_set_layout_default (GtkButtonBoxStyle layout) /* get default value for spacing */ -gint +gint gtk_hbutton_box_get_spacing_default (void) { return default_spacing; @@ -96,5 +92,11 @@ gtk_hbutton_box_get_layout_default (void) return default_layout_style; } +GtkButtonBoxStyle +_gtk_hbutton_box_get_layout_default (void) +{ + return default_layout_style; +} + #define __GTK_HBUTTON_BOX_C__ #include "gtkaliasdef.c" diff --git a/gtk/gtkhbbox.h b/gtk/gtkhbbox.h index 65d6df975a..25eecba106 100644 --- a/gtk/gtkhbbox.h +++ b/gtk/gtkhbbox.h @@ -72,6 +72,9 @@ void gtk_hbutton_box_set_spacing_default (gint spacing); void gtk_hbutton_box_set_layout_default (GtkButtonBoxStyle layout); #endif +/* private API */ +GtkButtonBoxStyle _gtk_hbutton_box_get_layout_default (void); + G_END_DECLS #endif /* __GTK_HBUTTON_BOX_H__ */ diff --git a/gtk/gtkiconfactory.c b/gtk/gtkiconfactory.c index cced1108e5..145d935e8e 100644 --- a/gtk/gtkiconfactory.c +++ b/gtk/gtkiconfactory.c @@ -21,7 +21,7 @@ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS * file for a list of people on the GTK+ Team. See the ChangeLog * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. */ #include "config.h" @@ -54,7 +54,7 @@ typedef enum { struct _GtkIconSource { GtkIconSourceType type; - + union { gchar *icon_name; gchar *filename; @@ -126,7 +126,7 @@ static void gtk_icon_factory_class_init (GtkIconFactoryClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - + object_class->finalize = gtk_icon_factory_finalize; } @@ -150,11 +150,11 @@ gtk_icon_factory_finalize (GObject *object) GtkIconFactory *factory = GTK_ICON_FACTORY (object); all_icon_factories = g_slist_remove (all_icon_factories, factory); - + g_hash_table_foreach (factory->icons, free_icon_set, NULL); - + g_hash_table_destroy (factory->icons); - + G_OBJECT_CLASS (gtk_icon_factory_parent_class)->finalize (object); } @@ -174,9 +174,9 @@ gtk_icon_factory_finalize (GObject *object) * gtk_icon_factory_remove_default(). Applications with icons should * add a default icon factory with their icons, which will allow * themes to override the icons for the application. - * + * * Return value: a new #GtkIconFactory - **/ + */ GtkIconFactory* gtk_icon_factory_new (void) { @@ -199,8 +199,7 @@ gtk_icon_factory_new (void) * override your application's default icons. If an icon already * existed in @factory for @stock_id, it is unreferenced and replaced * with the new @icon_set. - * - **/ + */ void gtk_icon_factory_add (GtkIconFactory *factory, const gchar *stock_id, @@ -211,14 +210,14 @@ gtk_icon_factory_add (GtkIconFactory *factory, g_return_if_fail (GTK_IS_ICON_FACTORY (factory)); g_return_if_fail (stock_id != NULL); - g_return_if_fail (icon_set != NULL); + g_return_if_fail (icon_set != NULL); g_hash_table_lookup_extended (factory->icons, stock_id, &old_key, &old_value); if (old_value == icon_set) return; - + gtk_icon_set_ref (icon_set); /* GHashTable key memory management is so fantastically broken. */ @@ -235,22 +234,22 @@ gtk_icon_factory_add (GtkIconFactory *factory, * gtk_icon_factory_lookup: * @factory: a #GtkIconFactory * @stock_id: an icon name - * + * * Looks up @stock_id in the icon factory, returning an icon set * if found, otherwise %NULL. For display to the user, you should * use gtk_style_lookup_icon_set() on the #GtkStyle for the * widget that will display the icon, instead of using this * function directly, so that themes are taken into account. - * + * * Return value: icon set of @stock_id. - **/ + */ GtkIconSet * gtk_icon_factory_lookup (GtkIconFactory *factory, const gchar *stock_id) { g_return_val_if_fail (GTK_IS_ICON_FACTORY (factory), NULL); g_return_val_if_fail (stock_id != NULL, NULL); - + return g_hash_table_lookup (factory->icons, stock_id); } @@ -260,22 +259,21 @@ static GSList *default_factories = NULL; /** * gtk_icon_factory_add_default: * @factory: a #GtkIconFactory - * + * * Adds an icon factory to the list of icon factories searched by * gtk_style_lookup_icon_set(). This means that, for example, * gtk_image_new_from_stock() will be able to find icons in @factory. * There will normally be an icon factory added for each library or * application that comes with icons. The default icon factories * can be overridden by themes. - * - **/ + */ void gtk_icon_factory_add_default (GtkIconFactory *factory) { g_return_if_fail (GTK_IS_ICON_FACTORY (factory)); g_object_ref (factory); - + default_factories = g_slist_prepend (default_factories, factory); } @@ -286,8 +284,7 @@ gtk_icon_factory_add_default (GtkIconFactory *factory) * Removes an icon factory from the list of default icon * factories. Not normally used; you might use it for a library that * can be unloaded or shut down. - * - **/ + */ void gtk_icon_factory_remove_default (GtkIconFactory *factory) { @@ -318,17 +315,16 @@ _gtk_icon_factory_ensure_default_icons (void) * the #GtkStyle for the widget that will display the icon, instead of * using this function directly, so that themes are taken into * account. - * - * + * * Return value: a #GtkIconSet, or %NULL - **/ + */ GtkIconSet * gtk_icon_factory_lookup_default (const gchar *stock_id) { GSList *tmp_list; g_return_val_if_fail (stock_id != NULL, NULL); - + tmp_list = default_factories; while (tmp_list != NULL) { @@ -338,12 +334,12 @@ gtk_icon_factory_lookup_default (const gchar *stock_id) if (icon_set) return icon_set; - + tmp_list = g_slist_next (tmp_list); } _gtk_icon_factory_ensure_default_icons (); - + return gtk_icon_factory_lookup (gtk_default_icons, stock_id); } @@ -357,7 +353,7 @@ register_stock_icon (GtkIconFactory *factory, source.type = GTK_ICON_SOURCE_STATIC_ICON_NAME; source.source.icon_name = (gchar *)stock_id; gtk_icon_set_add_source (set, &source); - + gtk_icon_factory_add (factory, stock_id, set); gtk_icon_set_unref (set); } @@ -375,12 +371,12 @@ register_bidi_stock_icon (GtkIconFactory *factory, source.source.icon_name = (gchar *)stock_id_ltr; source.direction = GTK_TEXT_DIR_LTR; gtk_icon_set_add_source (set, &source); - + source.type = GTK_ICON_SOURCE_STATIC_ICON_NAME; source.source.icon_name = (gchar *)stock_id_rtl; source.direction = GTK_TEXT_DIR_RTL; gtk_icon_set_add_source (set, &source); - + gtk_icon_factory_add (factory, stock_id, set); gtk_icon_set_unref (set); } @@ -416,9 +412,9 @@ get_default_icons (GtkIconFactory *factory) register_stock_icon (factory, GTK_STOCK_GO_DOWN); register_stock_icon (factory, GTK_STOCK_EXECUTE); register_stock_icon (factory, GTK_STOCK_QUIT); - register_bidi_stock_icon (factory, - GTK_STOCK_GOTO_FIRST, - GTK_STOCK_GOTO_FIRST "-ltr", + register_bidi_stock_icon (factory, + GTK_STOCK_GOTO_FIRST, + GTK_STOCK_GOTO_FIRST "-ltr", GTK_STOCK_GOTO_FIRST "-rtl"); register_stock_icon (factory, GTK_STOCK_SELECT_FONT); register_stock_icon (factory, GTK_STOCK_FULLSCREEN); @@ -427,15 +423,15 @@ get_default_icons (GtkIconFactory *factory) register_stock_icon (factory, GTK_STOCK_HELP); register_stock_icon (factory, GTK_STOCK_HOME); register_stock_icon (factory, GTK_STOCK_INFO); - register_bidi_stock_icon (factory, + register_bidi_stock_icon (factory, GTK_STOCK_JUMP_TO, GTK_STOCK_JUMP_TO "-ltr", GTK_STOCK_JUMP_TO "-rtl"); - register_bidi_stock_icon (factory, + register_bidi_stock_icon (factory, GTK_STOCK_GOTO_LAST, GTK_STOCK_GOTO_LAST "-ltr", GTK_STOCK_GOTO_LAST "-rtl"); - register_bidi_stock_icon (factory, + register_bidi_stock_icon (factory, GTK_STOCK_GO_BACK, GTK_STOCK_GO_BACK "-ltr", GTK_STOCK_GO_BACK "-rtl"); @@ -457,17 +453,17 @@ get_default_icons (GtkIconFactory *factory) register_stock_icon (factory, GTK_STOCK_PRINT_REPORT); register_stock_icon (factory, GTK_STOCK_PRINT_WARNING); register_stock_icon (factory, GTK_STOCK_PROPERTIES); - register_bidi_stock_icon (factory, + register_bidi_stock_icon (factory, GTK_STOCK_REDO, GTK_STOCK_REDO "-ltr", GTK_STOCK_REDO "-rtl"); register_stock_icon (factory, GTK_STOCK_REMOVE); register_stock_icon (factory, GTK_STOCK_REFRESH); - register_bidi_stock_icon (factory, + register_bidi_stock_icon (factory, GTK_STOCK_REVERT_TO_SAVED, GTK_STOCK_REVERT_TO_SAVED "-ltr", GTK_STOCK_REVERT_TO_SAVED "-rtl"); - register_bidi_stock_icon (factory, + register_bidi_stock_icon (factory, GTK_STOCK_GO_FORWARD, GTK_STOCK_GO_FORWARD "-ltr", GTK_STOCK_GO_FORWARD "-rtl"); @@ -484,21 +480,21 @@ get_default_icons (GtkIconFactory *factory) register_stock_icon (factory, GTK_STOCK_ITALIC); register_stock_icon (factory, GTK_STOCK_STRIKETHROUGH); register_stock_icon (factory, GTK_STOCK_UNDERLINE); - register_bidi_stock_icon (factory, + register_bidi_stock_icon (factory, GTK_STOCK_INDENT, GTK_STOCK_INDENT "-ltr", GTK_STOCK_INDENT "-rtl"); - register_bidi_stock_icon (factory, + register_bidi_stock_icon (factory, GTK_STOCK_UNINDENT, GTK_STOCK_UNINDENT "-ltr", GTK_STOCK_UNINDENT "-rtl"); register_stock_icon (factory, GTK_STOCK_GOTO_TOP); register_stock_icon (factory, GTK_STOCK_DELETE); - register_bidi_stock_icon (factory, + register_bidi_stock_icon (factory, GTK_STOCK_UNDELETE, GTK_STOCK_UNDELETE "-ltr", GTK_STOCK_UNDELETE "-rtl"); - register_bidi_stock_icon (factory, + register_bidi_stock_icon (factory, GTK_STOCK_UNDO, GTK_STOCK_UNDO "-ltr", GTK_STOCK_UNDO "-rtl"); @@ -510,25 +506,25 @@ get_default_icons (GtkIconFactory *factory) register_stock_icon (factory, GTK_STOCK_DISCONNECT); register_stock_icon (factory, GTK_STOCK_EDIT); register_stock_icon (factory, GTK_STOCK_CAPS_LOCK_WARNING); - register_bidi_stock_icon (factory, + register_bidi_stock_icon (factory, GTK_STOCK_MEDIA_FORWARD, GTK_STOCK_MEDIA_FORWARD "-ltr", GTK_STOCK_MEDIA_FORWARD "-rtl"); - register_bidi_stock_icon (factory, + register_bidi_stock_icon (factory, GTK_STOCK_MEDIA_NEXT, GTK_STOCK_MEDIA_NEXT "-ltr", GTK_STOCK_MEDIA_NEXT "-rtl"); register_stock_icon (factory, GTK_STOCK_MEDIA_PAUSE); - register_bidi_stock_icon (factory, + register_bidi_stock_icon (factory, GTK_STOCK_MEDIA_PLAY, GTK_STOCK_MEDIA_PLAY "-ltr", GTK_STOCK_MEDIA_PLAY "-rtl"); - register_bidi_stock_icon (factory, + register_bidi_stock_icon (factory, GTK_STOCK_MEDIA_PREVIOUS, GTK_STOCK_MEDIA_PREVIOUS "-ltr", GTK_STOCK_MEDIA_PREVIOUS "-rtl"); register_stock_icon (factory, GTK_STOCK_MEDIA_RECORD); - register_bidi_stock_icon (factory, + register_bidi_stock_icon (factory, GTK_STOCK_MEDIA_REWIND, GTK_STOCK_MEDIA_REWIND "-ltr", GTK_STOCK_MEDIA_REWIND "-rtl"); @@ -554,7 +550,7 @@ struct _IconSize { gint size; gchar *name; - + gint width; gint height; }; @@ -589,7 +585,7 @@ init_icon_sizes (void) gint i; icon_aliases = g_hash_table_new (g_str_hash, g_str_equal); - + icon_sizes = g_new (IconSize, NUM_BUILTIN_SIZES); icon_sizes_allocated = NUM_BUILTIN_SIZES; icon_sizes_used = NUM_BUILTIN_SIZES; @@ -604,7 +600,7 @@ init_icon_sizes (void) * Even if we did I suppose removing the builtin sizes would be * disallowed. */ - + icon_sizes[GTK_ICON_SIZE_MENU].size = GTK_ICON_SIZE_MENU; icon_sizes[GTK_ICON_SIZE_MENU].name = "gtk-menu"; icon_sizes[GTK_ICON_SIZE_MENU].width = 16; @@ -619,7 +615,7 @@ init_icon_sizes (void) icon_sizes[GTK_ICON_SIZE_SMALL_TOOLBAR].name = "gtk-small-toolbar"; icon_sizes[GTK_ICON_SIZE_SMALL_TOOLBAR].width = 18; icon_sizes[GTK_ICON_SIZE_SMALL_TOOLBAR].height = 18; - + icon_sizes[GTK_ICON_SIZE_LARGE_TOOLBAR].size = GTK_ICON_SIZE_LARGE_TOOLBAR; icon_sizes[GTK_ICON_SIZE_LARGE_TOOLBAR].name = "gtk-large-toolbar"; icon_sizes[GTK_ICON_SIZE_LARGE_TOOLBAR].width = 24; @@ -642,10 +638,10 @@ init_icon_sizes (void) while (i < NUM_BUILTIN_SIZES) { gtk_icon_size_register_alias (icon_sizes[i].name, icon_sizes[i].size); - + ++i; } - + #undef NUM_BUILTIN_SIZES } } @@ -695,7 +691,7 @@ icon_size_set_for_settings (GtkSettings *settings, if (size == GTK_ICON_SIZE_INVALID) /* Reserve a place */ size = icon_size_register_intern (size_name, -1, -1); - + settings_sizes = get_settings_sizes (settings, NULL); if (size >= settings_sizes->len) { @@ -707,7 +703,7 @@ icon_size_set_for_settings (GtkSettings *settings, } settings_size = &g_array_index (settings_sizes, SettingsIconSize, size); - + settings_size->width = width; settings_size->height = height; } @@ -721,7 +717,7 @@ scan_icon_size_name (const char **pos, GString *out) while (g_ascii_isspace (*p)) p++; - + if (!((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z') || *p == '_' || *p == '-')) @@ -755,7 +751,7 @@ icon_size_setting_parse (GtkSettings *settings, while (pango_skip_space (&p)) { gint width, height; - + if (!scan_icon_size_name (&p, name_buf)) goto err; @@ -845,10 +841,10 @@ icon_sizes_init_for_settings (GtkSettings *settings) "notify::gtk-icon-sizes", G_CALLBACK (icon_size_settings_changed), NULL); - + icon_size_set_all_from_settings (settings); } - + static gboolean icon_size_lookup_intern (GtkSettings *settings, GtkIconSize size, @@ -858,7 +854,7 @@ icon_size_lookup_intern (GtkSettings *settings, GArray *settings_sizes; gint width_for_settings = -1; gint height_for_settings = -1; - + init_icon_sizes (); if (size == (GtkIconSize)-1) @@ -873,17 +869,18 @@ icon_size_lookup_intern (GtkSettings *settings, if (settings) { gboolean initial = FALSE; - + settings_sizes = get_settings_sizes (settings, &initial); + if (initial) icon_sizes_init_for_settings (settings); - + if (size < settings_sizes->len) { SettingsIconSize *settings_size; - + settings_size = &g_array_index (settings_sizes, SettingsIconSize, size); - + width_for_settings = settings_size->width; height_for_settings = settings_size->height; } @@ -907,7 +904,7 @@ icon_size_lookup_intern (GtkSettings *settings, * @height: location to store icon height * * Obtains the pixel size of a semantic icon size, possibly - * modified by user preferences for a particular + * modified by user preferences for a particular * #GtkSettings. Normally @size would be * #GTK_ICON_SIZE_MENU, #GTK_ICON_SIZE_BUTTON, etc. This function * isn't normally needed, gtk_widget_render_icon() is the usual @@ -916,11 +913,11 @@ icon_size_lookup_intern (GtkSettings *settings, * the width/height returned by gtk_icon_size_lookup(), because themes * are free to render the pixbuf however they like, including changing * the usual size. - * + * * Return value: %TRUE if @size was a valid size * * Since: 2.2 - **/ + */ gboolean gtk_icon_size_lookup_for_settings (GtkSettings *settings, GtkIconSize size, @@ -949,9 +946,9 @@ gtk_icon_size_lookup_for_settings (GtkSettings *settings, * the width/height returned by gtk_icon_size_lookup(), because themes * are free to render the pixbuf however they like, including changing * the usual size. - * + * * Return value: %TRUE if @size was a valid size - **/ + */ gboolean gtk_icon_size_lookup (GtkIconSize size, gint *widthp, @@ -971,7 +968,7 @@ icon_size_register_intern (const gchar *name, { IconAlias *old_alias; GtkIconSize size; - + init_icon_sizes (); old_alias = g_hash_table_lookup (icon_aliases, name); @@ -1018,8 +1015,7 @@ icon_size_register_intern (const gchar *name, * etc. Returns the integer value for the size. * * Returns: integer value representing the size - * - **/ + */ GtkIconSize gtk_icon_size_register (const gchar *name, gint width, @@ -1028,7 +1024,7 @@ gtk_icon_size_register (const gchar *name, g_return_val_if_fail (name != NULL, 0); g_return_val_if_fail (width > 0, 0); g_return_val_if_fail (height > 0, 0); - + return icon_size_register_intern (name, width, height); } @@ -1040,14 +1036,13 @@ gtk_icon_size_register (const gchar *name, * Registers @alias as another name for @target. * So calling gtk_icon_size_from_name() with @alias as argument * will return @target. - * - **/ + */ void gtk_icon_size_register_alias (const gchar *alias, GtkIconSize target) { IconAlias *ia; - + g_return_if_fail (alias != NULL); init_icon_sizes (); @@ -1077,20 +1072,20 @@ gtk_icon_size_register_alias (const gchar *alias, } } -/** +/** * gtk_icon_size_from_name: * @name: the name to look up. * @returns: the icon size with the given name. - * + * * Looks up the icon size associated with @name. - **/ + */ GtkIconSize gtk_icon_size_from_name (const gchar *name) { IconAlias *ia; init_icon_sizes (); - + ia = g_hash_table_lookup (icon_aliases, name); if (ia && icon_sizes[ia->target].width > 0) @@ -1103,10 +1098,10 @@ gtk_icon_size_from_name (const gchar *name) * gtk_icon_size_get_name: * @size: a #GtkIconSize. * @returns: the name of the given icon size. - * - * Gets the canonical name of the given icon size. The returned string + * + * Gets the canonical name of the given icon size. The returned string * is statically allocated and should not be freed. - **/ + */ G_CONST_RETURN gchar* gtk_icon_size_get_name (GtkIconSize size) { @@ -1164,7 +1159,7 @@ static guint cache_serial = 0; /** * gtk_icon_set_new: - * + * * Creates a new #GtkIconSet. A #GtkIconSet represents a single icon * in various sizes and widget states. It can provide a #GdkPixbuf * for a given size and state on request, and automatically caches @@ -1174,9 +1169,9 @@ static guint cache_serial = 0; * using #GtkIconSet directly. The one case where you'd use * #GtkIconSet is to create application-specific icon sets to place in * a #GtkIconFactory. - * + * * Return value: a new #GtkIconSet - **/ + */ GtkIconSet* gtk_icon_set_new (void) { @@ -1189,22 +1184,22 @@ gtk_icon_set_new (void) icon_set->cache = NULL; icon_set->cache_size = 0; icon_set->cache_serial = cache_serial; - + return icon_set; } /** * gtk_icon_set_new_from_pixbuf: * @pixbuf: a #GdkPixbuf - * + * * Creates a new #GtkIconSet with @pixbuf as the default/fallback * source image. If you don't add any additional #GtkIconSource to the * icon set, all variants of the icon will be created from @pixbuf, * using scaling, pixelation, etc. as required to adjust the icon size * or make the icon look insensitive/prelighted. - * + * * Return value: a new #GtkIconSet - **/ + */ GtkIconSet * gtk_icon_set_new_from_pixbuf (GdkPixbuf *pixbuf) { @@ -1219,7 +1214,7 @@ gtk_icon_set_new_from_pixbuf (GdkPixbuf *pixbuf) gtk_icon_source_set_pixbuf (&source, pixbuf); gtk_icon_set_add_source (set, &source); gtk_icon_source_set_pixbuf (&source, NULL); - + return set; } @@ -1227,11 +1222,11 @@ gtk_icon_set_new_from_pixbuf (GdkPixbuf *pixbuf) /** * gtk_icon_set_ref: * @icon_set: a #GtkIconSet. - * + * * Increments the reference count on @icon_set. - * + * * Return value: @icon_set. - **/ + */ GtkIconSet* gtk_icon_set_ref (GtkIconSet *icon_set) { @@ -1246,10 +1241,10 @@ gtk_icon_set_ref (GtkIconSet *icon_set) /** * gtk_icon_set_unref: * @icon_set: a #GtkIconSet - * + * * Decrements the reference count on @icon_set, and frees memory * if the reference count reaches 0. - **/ + */ void gtk_icon_set_unref (GtkIconSet *icon_set) { @@ -1279,7 +1274,7 @@ GType gtk_icon_set_get_type (void) { static GType our_type = 0; - + if (our_type == 0) our_type = g_boxed_type_register_static (I_("GtkIconSet"), (GBoxedCopyFunc) gtk_icon_set_ref, @@ -1291,9 +1286,9 @@ gtk_icon_set_get_type (void) /** * gtk_icon_set_copy: * @icon_set: a #GtkIconSet - * - * Copies @icon_set by value. - * + * + * Copies @icon_set by value. + * * Return value: a new #GtkIconSet identical to the first. **/ GtkIconSet* @@ -1301,7 +1296,7 @@ gtk_icon_set_copy (GtkIconSet *icon_set) { GtkIconSet *copy; GSList *tmp_list; - + copy = gtk_icon_set_new (); tmp_list = icon_set->sources; @@ -1318,7 +1313,7 @@ gtk_icon_set_copy (GtkIconSet *icon_set) copy->cache = copy_cache (icon_set, copy); copy->cache_size = icon_set->cache_size; copy->cache_serial = icon_set->cache_serial; - + return copy; } @@ -1334,8 +1329,8 @@ sizes_equivalent (GtkIconSize lhs, */ #if 1 return lhs == rhs; -#else - +#else + gint r_w, r_h, l_w, l_h; icon_size_lookup_intern (NULL, rhs, &r_w, &r_h); @@ -1354,7 +1349,7 @@ find_best_matching_source (GtkIconSet *icon_set, { GtkIconSource *source; GSList *tmp_list; - + /* We need to find the best icon source. Direction matters more * than state, state matters more than size. icon_set->sources * is sorted according to wildness, so if we take the first @@ -1362,13 +1357,13 @@ find_best_matching_source (GtkIconSet *icon_set, * multiple matches for a given "wildness" then the RC file contained * dumb stuff, and we end up with an arbitrary matching source) */ - + source = NULL; tmp_list = icon_set->sources; while (tmp_list != NULL) { GtkIconSource *s = tmp_list->data; - + if ((s->any_direction || (s->direction == direction)) && (s->any_state || (s->state == state)) && (s->any_size || size == (GtkIconSize)-1 || (sizes_equivalent (size, s->size)))) @@ -1379,13 +1374,13 @@ find_best_matching_source (GtkIconSet *icon_set, break; } } - + tmp_list = g_slist_next (tmp_list); } return source; } - + static gboolean ensure_filename_pixbuf (GtkIconSet *icon_set, GtkIconSource *source) @@ -1393,9 +1388,9 @@ ensure_filename_pixbuf (GtkIconSet *icon_set, if (source->filename_pixbuf == NULL) { GError *error = NULL; - + source->filename_pixbuf = gdk_pixbuf_new_from_file (source->source.filename, &error); - + if (source->filename_pixbuf == NULL) { /* Remove this icon source so we don't keep trying to @@ -1403,18 +1398,18 @@ ensure_filename_pixbuf (GtkIconSet *icon_set, */ g_warning (_("Error loading icon: %s"), error->message); g_error_free (error); - + icon_set->sources = g_slist_remove (icon_set->sources, source); - + gtk_icon_source_free (source); return FALSE; } } - + return TRUE; } - + static GdkPixbuf * render_icon_name_pixbuf (GtkIconSource *icon_source, GtkStyle *style, @@ -1433,7 +1428,7 @@ render_icon_name_pixbuf (GtkIconSource *icon_source, gint width, height, pixel_size; gint *sizes, *s, dist; GError *error = NULL; - + if (widget && gtk_widget_has_screen (widget)) screen = gtk_widget_get_screen (widget); else if (style && style->colormap) @@ -1452,8 +1447,7 @@ render_icon_name_pixbuf (GtkIconSource *icon_source, { if (size == (GtkIconSize)-1) { - /* Find an available size close to 48 - */ + /* Find an available size close to 48 */ sizes = gtk_icon_theme_get_icon_sizes (icon_theme, icon_source->source.icon_name); dist = 1000; width = height = 48; @@ -1472,7 +1466,7 @@ render_icon_name_pixbuf (GtkIconSource *icon_source, dist = 48 - *s; } } - else + else { if (*s - 48 < dist) { @@ -1481,7 +1475,7 @@ render_icon_name_pixbuf (GtkIconSource *icon_source, } } } - + g_free (sizes); } else @@ -1500,12 +1494,13 @@ render_icon_name_pixbuf (GtkIconSource *icon_source, if (!tmp_pixbuf) { - g_warning ("Error loading theme icon '%s' for stock: %s", - icon_source->source.icon_name, error->message); - g_error_free (error); + g_warning ("Error loading theme icon '%s' for stock: %s", + icon_source->source.icon_name, error ? error->message : ""); + if (error) + g_error_free (error); return NULL; } - + tmp_source = *icon_source; tmp_source.type = GTK_ICON_SOURCE_PIXBUF; tmp_source.source.pixbuf = tmp_pixbuf; @@ -1547,7 +1542,7 @@ find_and_render_icon_source (GtkIconSet *icon_set, while (pixbuf == NULL) { GtkIconSource *source = find_best_matching_source (icon_set, direction, state, size, failed); - + if (source == NULL) break; @@ -1612,7 +1607,7 @@ render_fallback_image (GtkStyle *style, gtk_icon_source_set_pixbuf (&fallback_source, pixbuf); g_object_unref (pixbuf); } - + return gtk_style_render_icon (style, &fallback_source, direction, @@ -1636,16 +1631,16 @@ render_fallback_image (GtkStyle *style, * @detail: detail to pass to the theme engine, or %NULL. * Note that passing a detail of anything but %NULL * will disable caching. - * + * * Renders an icon using gtk_style_render_icon(). In most cases, * gtk_widget_render_icon() is better, since it automatically provides * most of the arguments from the current widget settings. This * function never returns %NULL; if the icon can't be rendered * (perhaps because an image file fails to load), a default "missing * image" icon will be returned instead. - * + * * Return value: a #GdkPixbuf to be displayed - **/ + */ GdkPixbuf* gtk_icon_set_render_icon (GtkIconSet *icon_set, GtkStyle *style, @@ -1656,7 +1651,7 @@ gtk_icon_set_render_icon (GtkIconSet *icon_set, const char *detail) { GdkPixbuf *icon; - + g_return_val_if_fail (icon_set != NULL, NULL); g_return_val_if_fail (style == NULL || GTK_IS_STYLE (style), NULL); @@ -1667,7 +1662,7 @@ gtk_icon_set_render_icon (GtkIconSet *icon_set, { icon = find_in_cache (icon_set, style, direction, state, size); - + if (icon) { g_object_ref (icon); @@ -1684,7 +1679,7 @@ gtk_icon_set_render_icon (GtkIconSet *icon_set, if (detail == NULL) add_to_cache (icon_set, style, direction, state, size, icon); - + return icon; } @@ -1726,7 +1721,7 @@ icon_source_compare (gconstpointer ap, gconstpointer bp) * gtk_icon_set_render_icon(), but #GtkIconSet needs base images to * work with. The base images and when to use them are described by * a #GtkIconSource. - * + * * This function copies @source, so you can reuse the same source immediately * without affecting the icon set. * @@ -1745,10 +1740,9 @@ icon_source_compare (gconstpointer ap, gconstpointer bp) * * gtk_icon_set_new_from_pixbuf() creates a new icon set with a * default icon source based on the given pixbuf. - * - **/ + */ void -gtk_icon_set_add_source (GtkIconSet *icon_set, +gtk_icon_set_add_source (GtkIconSet *icon_set, const GtkIconSource *source) { g_return_if_fail (icon_set != NULL); @@ -1759,7 +1753,7 @@ gtk_icon_set_add_source (GtkIconSet *icon_set, g_warning ("Useless empty GtkIconSource"); return; } - + icon_set->sources = g_slist_insert_sorted (icon_set->sources, gtk_icon_source_copy (source), icon_source_compare); @@ -1773,8 +1767,7 @@ gtk_icon_set_add_source (GtkIconSet *icon_set, * * Obtains a list of icon sizes this icon set can render. The returned * array must be freed with g_free(). - * - **/ + */ void gtk_icon_set_get_sizes (GtkIconSet *icon_set, GtkIconSize **sizes, @@ -1783,11 +1776,11 @@ gtk_icon_set_get_sizes (GtkIconSet *icon_set, GSList *tmp_list; gboolean all_sizes = FALSE; GSList *specifics = NULL; - + g_return_if_fail (icon_set != NULL); g_return_if_fail (sizes != NULL); g_return_if_fail (n_sizes != NULL); - + tmp_list = icon_set->sources; while (tmp_list != NULL) { @@ -1802,7 +1795,7 @@ gtk_icon_set_get_sizes (GtkIconSet *icon_set, } else specifics = g_slist_prepend (specifics, GINT_TO_POINTER (source->size)); - + tmp_list = g_slist_next (tmp_list); } @@ -1812,11 +1805,11 @@ gtk_icon_set_get_sizes (GtkIconSet *icon_set, gint i; init_icon_sizes (); - + *sizes = g_new (GtkIconSize, icon_sizes_used); *n_sizes = icon_sizes_used - 1; - - i = 1; + + i = 1; while (i < icon_sizes_used) { (*sizes)[i - 1] = icon_sizes[i].size; @@ -1826,7 +1819,7 @@ gtk_icon_set_get_sizes (GtkIconSet *icon_set, else { gint i; - + *n_sizes = g_slist_length (specifics); *sizes = g_new (GtkIconSize, *n_sizes); @@ -1847,21 +1840,21 @@ gtk_icon_set_get_sizes (GtkIconSet *icon_set, /** * gtk_icon_source_new: - * + * * Creates a new #GtkIconSource. A #GtkIconSource contains a #GdkPixbuf (or * image filename) that serves as the base image for one or more of the * icons in a #GtkIconSet, along with a specification for which icons in the * icon set will be based on that pixbuf or image file. An icon set contains * a set of icons that represent "the same" logical concept in different states, * different global text directions, and different sizes. - * + * * So for example a web browser's "Back to Previous Page" icon might * point in a different direction in Hebrew and in English; it might * look different when insensitive; and it might change size depending * on toolbar mode (small/large icons). So a single icon set would * contain all those variants of the icon. #GtkIconSet contains a list * of #GtkIconSource from which it can derive specific icon variants in - * the set. + * the set. * * In the simplest case, #GtkIconSet contains one source pixbuf from * which it derives all variants. The convenience function @@ -1876,46 +1869,46 @@ gtk_icon_set_get_sizes (GtkIconSet *icon_set, * By default, the icon source has all parameters wildcarded. That is, * the icon source will be used as the base icon for any desired text * direction, widget state, or icon size. - * + * * Return value: a new #GtkIconSource - **/ + */ GtkIconSource* gtk_icon_source_new (void) { GtkIconSource *src; - + src = g_new0 (GtkIconSource, 1); src->direction = GTK_TEXT_DIR_NONE; src->size = GTK_ICON_SIZE_INVALID; src->state = GTK_STATE_NORMAL; - + src->any_direction = TRUE; src->any_state = TRUE; src->any_size = TRUE; - + return src; } /** * gtk_icon_source_copy: * @source: a #GtkIconSource - * + * * Creates a copy of @source; mostly useful for language bindings. - * + * * Return value: a new #GtkIconSource - **/ + */ GtkIconSource* gtk_icon_source_copy (const GtkIconSource *source) { GtkIconSource *copy; - + g_return_val_if_fail (source != NULL, NULL); copy = g_new (GtkIconSource, 1); *copy = *source; - + switch (copy->type) { case GTK_ICON_SOURCE_EMPTY: @@ -1945,10 +1938,10 @@ gtk_icon_source_copy (const GtkIconSource *source) /** * gtk_icon_source_free: * @source: a #GtkIconSource - * + * * Frees a dynamically-allocated icon source, along with its * filename, size, and pixbuf fields if those are not %NULL. - **/ + */ void gtk_icon_source_free (GtkIconSource *source) { @@ -1962,7 +1955,7 @@ GType gtk_icon_source_get_type (void) { static GType our_type = 0; - + if (our_type == 0) our_type = g_boxed_type_register_static (I_("GtkIconSource"), (GBoxedCopyFunc) gtk_icon_source_copy, @@ -2012,8 +2005,8 @@ icon_source_clear (GtkIconSource *source) * @filename: image file to use * * Sets the name of an image file to use as a base image when creating - * icon variants for #GtkIconSet. The filename must be absolute. - **/ + * icon variants for #GtkIconSet. The filename must be absolute. + */ void gtk_icon_source_set_filename (GtkIconSource *source, const gchar *filename) @@ -2024,9 +2017,9 @@ gtk_icon_source_set_filename (GtkIconSource *source, if (source->type == GTK_ICON_SOURCE_FILENAME && source->source.filename == filename) return; - + icon_source_clear (source); - + if (filename != NULL) { source->type = GTK_ICON_SOURCE_FILENAME; @@ -2044,7 +2037,7 @@ gtk_icon_source_set_filename (GtkIconSource *source, * * Sets the name of an icon to look up in the current icon theme * to use as a base image when creating icon variants for #GtkIconSet. - **/ + */ void gtk_icon_source_set_icon_name (GtkIconSource *source, const gchar *icon_name) @@ -2056,7 +2049,7 @@ gtk_icon_source_set_icon_name (GtkIconSource *source, return; icon_source_clear (source); - + if (icon_name != NULL) { source->type = GTK_ICON_SOURCE_ICON_NAME; @@ -2071,20 +2064,20 @@ gtk_icon_source_set_icon_name (GtkIconSource *source, * * Sets a pixbuf to use as a base image when creating icon variants * for #GtkIconSet. - **/ + */ void gtk_icon_source_set_pixbuf (GtkIconSource *source, GdkPixbuf *pixbuf) { g_return_if_fail (source != NULL); g_return_if_fail (pixbuf == NULL || GDK_IS_PIXBUF (pixbuf)); - + if (source->type == GTK_ICON_SOURCE_PIXBUF && source->source.pixbuf == pixbuf) return; icon_source_clear (source); - + if (pixbuf != NULL) { source->type = GTK_ICON_SOURCE_PIXBUF; @@ -2095,14 +2088,14 @@ gtk_icon_source_set_pixbuf (GtkIconSource *source, /** * gtk_icon_source_get_filename: * @source: a #GtkIconSource - * + * * Retrieves the source filename, or %NULL if none is set. The * filename is not a copy, and should not be modified or expected to * persist beyond the lifetime of the icon source. - * + * * Return value: image filename. This string must not be modified * or freed. - **/ + */ G_CONST_RETURN gchar* gtk_icon_source_get_filename (const GtkIconSource *source) { @@ -2117,13 +2110,13 @@ gtk_icon_source_get_filename (const GtkIconSource *source) /** * gtk_icon_source_get_icon_name: * @source: a #GtkIconSource - * + * * Retrieves the source icon name, or %NULL if none is set. The * icon_name is not a copy, and should not be modified or expected to * persist beyond the lifetime of the icon source. - * + * * Return value: icon name. This string must not be modified or freed. - **/ + */ G_CONST_RETURN gchar* gtk_icon_source_get_icon_name (const GtkIconSource *source) { @@ -2139,7 +2132,7 @@ gtk_icon_source_get_icon_name (const GtkIconSource *source) /** * gtk_icon_source_get_pixbuf: * @source: a #GtkIconSource - * + * * Retrieves the source pixbuf, or %NULL if none is set. * In addition, if a filename source is in use, this * function in some cases will return the pixbuf from @@ -2147,14 +2140,14 @@ gtk_icon_source_get_icon_name (const GtkIconSource *source) * for the GtkIconSource passed to the GtkStyle::render_icon() * virtual function. The reference count on the pixbuf is * not incremented. - * + * * Return value: source pixbuf - **/ + */ GdkPixbuf* gtk_icon_source_get_pixbuf (const GtkIconSource *source) { g_return_val_if_fail (source != NULL, NULL); - + if (source->type == GTK_ICON_SOURCE_PIXBUF) return source->source.pixbuf; else if (source->type == GTK_ICON_SOURCE_FILENAME) @@ -2177,8 +2170,7 @@ gtk_icon_source_get_pixbuf (const GtkIconSource *source) * * #GtkIconSet prefers non-wildcarded sources (exact matches) over * wildcarded sources, and will use an exact match when possible. - * - **/ + */ void gtk_icon_source_set_direction_wildcarded (GtkIconSource *source, gboolean setting) @@ -2206,7 +2198,7 @@ gtk_icon_source_set_direction_wildcarded (GtkIconSource *source, * produce an appropriate icon for a given state, for example * lightening an image on prelight, but will not modify source images * that match exactly. - **/ + */ void gtk_icon_source_set_state_wildcarded (GtkIconSource *source, gboolean setting) @@ -2234,40 +2226,40 @@ gtk_icon_source_set_state_wildcarded (GtkIconSource *source, * #GtkIconSet will normally scale wildcarded source images to produce * an appropriate icon at a given size, but will not change the size * of source images that match exactly. - **/ + */ void gtk_icon_source_set_size_wildcarded (GtkIconSource *source, gboolean setting) { g_return_if_fail (source != NULL); - source->any_size = setting != FALSE; + source->any_size = setting != FALSE; } /** * gtk_icon_source_get_size_wildcarded: * @source: a #GtkIconSource - * + * * Gets the value set by gtk_icon_source_set_size_wildcarded(). - * + * * Return value: %TRUE if this icon source is a base for any icon size variant - **/ + */ gboolean gtk_icon_source_get_size_wildcarded (const GtkIconSource *source) { g_return_val_if_fail (source != NULL, TRUE); - + return source->any_size; } /** * gtk_icon_source_get_state_wildcarded: * @source: a #GtkIconSource - * + * * Gets the value set by gtk_icon_source_set_state_wildcarded(). - * + * * Return value: %TRUE if this icon source is a base for any widget state variant - **/ + */ gboolean gtk_icon_source_get_state_wildcarded (const GtkIconSource *source) { @@ -2279,11 +2271,11 @@ gtk_icon_source_get_state_wildcarded (const GtkIconSource *source) /** * gtk_icon_source_get_direction_wildcarded: * @source: a #GtkIconSource - * + * * Gets the value set by gtk_icon_source_set_direction_wildcarded(). - * + * * Return value: %TRUE if this icon source is a base for any text direction variant - **/ + */ gboolean gtk_icon_source_get_direction_wildcarded (const GtkIconSource *source) { @@ -2299,13 +2291,12 @@ gtk_icon_source_get_direction_wildcarded (const GtkIconSource *source) * * Sets the text direction this icon source is intended to be used * with. - * + * * Setting the text direction on an icon source makes no difference * if the text direction is wildcarded. Therefore, you should usually * call gtk_icon_source_set_direction_wildcarded() to un-wildcard it * in addition to calling this function. - * - **/ + */ void gtk_icon_source_set_direction (GtkIconSource *source, GtkTextDirection direction) @@ -2322,13 +2313,12 @@ gtk_icon_source_set_direction (GtkIconSource *source, * * Sets the widget state this icon source is intended to be used * with. - * + * * Setting the widget state on an icon source makes no difference * if the state is wildcarded. Therefore, you should usually * call gtk_icon_source_set_state_wildcarded() to un-wildcard it * in addition to calling this function. - * - **/ + */ void gtk_icon_source_set_state (GtkIconSource *source, GtkStateType state) @@ -2345,13 +2335,12 @@ gtk_icon_source_set_state (GtkIconSource *source, * * Sets the icon size this icon source is intended to be used * with. - * + * * Setting the icon size on an icon source makes no difference * if the size is wildcarded. Therefore, you should usually * call gtk_icon_source_set_size_wildcarded() to un-wildcard it * in addition to calling this function. - * - **/ + */ void gtk_icon_source_set_size (GtkIconSource *source, GtkIconSize size) @@ -2364,13 +2353,13 @@ gtk_icon_source_set_size (GtkIconSource *source, /** * gtk_icon_source_get_direction: * @source: a #GtkIconSource - * + * * Obtains the text direction this icon source applies to. The return - * value is only useful/meaningful if the text direction is not + * value is only useful/meaningful if the text direction is not * wildcarded. - * + * * Return value: text direction this source matches - **/ + */ GtkTextDirection gtk_icon_source_get_direction (const GtkIconSource *source) { @@ -2382,13 +2371,13 @@ gtk_icon_source_get_direction (const GtkIconSource *source) /** * gtk_icon_source_get_state: * @source: a #GtkIconSource - * + * * Obtains the widget state this icon source applies to. The return * value is only useful/meaningful if the widget state is not * wildcarded. - * + * * Return value: widget state this source matches - **/ + */ GtkStateType gtk_icon_source_get_state (const GtkIconSource *source) { @@ -2400,12 +2389,12 @@ gtk_icon_source_get_state (const GtkIconSource *source) /** * gtk_icon_source_get_size: * @source: a #GtkIconSource - * + * * Obtains the icon size this source applies to. The return value * is only useful/meaningful if the icon size is not wildcarded. - * + * * Return value: icon size this source matches. - **/ + */ GtkIconSize gtk_icon_source_get_size (const GtkIconSource *source) { @@ -2463,7 +2452,7 @@ find_in_cache (GtkIconSet *icon_set, GSList *prev; ensure_cache_up_to_date (icon_set); - + prev = NULL; tmp_list = icon_set->cache; while (tmp_list != NULL) @@ -2482,10 +2471,10 @@ find_in_cache (GtkIconSet *icon_set, tmp_list->next = icon_set->cache; icon_set->cache = tmp_list; } - + return icon->pixbuf; } - + prev = tmp_list; tmp_list = g_slist_next (tmp_list); } @@ -2511,7 +2500,7 @@ add_to_cache (GtkIconSet *icon_set, * its address could be reused by another style, creating a * really weird bug */ - + if (style) g_object_ref (style); @@ -2527,12 +2516,12 @@ add_to_cache (GtkIconSet *icon_set, if (icon->style) attach_to_style (icon_set, icon->style); - + if (icon_set->cache_size >= NUM_CACHED_ICONS) { /* Remove oldest item in the cache */ GSList *tmp_list; - + tmp_list = icon_set->cache; /* Find next-to-last link */ @@ -2582,9 +2571,9 @@ clear_cache (GtkIconSet *icon_set, last_style = icon->style; } } - - cached_icon_free (icon); - + + cached_icon_free (icon); + tmp_list = g_slist_next (tmp_list); } @@ -2599,7 +2588,7 @@ copy_cache (GtkIconSet *icon_set, GSList *copy = NULL; ensure_cache_up_to_date (icon_set); - + tmp_list = icon_set->cache; while (tmp_list != NULL) { @@ -2613,13 +2602,13 @@ copy_cache (GtkIconSet *icon_set, attach_to_style (copy_recipient, icon_copy->style); g_object_ref (icon_copy->style); } - + g_object_ref (icon_copy->pixbuf); icon_copy->size = icon->size; - - copy = g_slist_prepend (copy, icon_copy); - + + copy = g_slist_prepend (copy, icon_copy); + tmp_list = g_slist_next (tmp_list); } @@ -2673,7 +2662,7 @@ iconsets_foreach (gpointer key, * time all cache entries will have the same style, * so this is faster anyway. */ - + clear_cache (icon_set, FALSE); } @@ -2681,7 +2670,7 @@ static void style_dnotify (gpointer data) { GHashTable *table = data; - + g_hash_table_foreach (table, iconsets_foreach, NULL); g_hash_table_destroy (table); @@ -2696,13 +2685,13 @@ _gtk_icon_set_invalidate_caches (void) /** * _gtk_icon_factory_list_ids: - * + * * Gets all known IDs stored in an existing icon factory. * The strings in the returned list aren't copied. * The list itself should be freed. - * + * * Return value: List of ids in icon factories - **/ + */ GList* _gtk_icon_factory_list_ids (void) { @@ -2712,18 +2701,18 @@ _gtk_icon_factory_list_ids (void) ids = NULL; _gtk_icon_factory_ensure_default_icons (); - + tmp_list = all_icon_factories; while (tmp_list != NULL) { GList *these_ids; - + GtkIconFactory *factory = GTK_ICON_FACTORY (tmp_list->data); these_ids = g_hash_table_get_keys (factory->icons); - + ids = g_list_concat (ids, these_ids); - + tmp_list = g_slist_next (tmp_list); } @@ -2733,7 +2722,7 @@ _gtk_icon_factory_list_ids (void) typedef struct { GSList *sources; gboolean in_source; - + } IconFactoryParserData; typedef struct { @@ -2764,7 +2753,7 @@ icon_source_start_element (GMarkupParseContext *context, IconSourceParserData *source_data; gchar *error_msg; GQuark error_domain; - + parser_data = (IconFactoryParserData*)user_data; if (!parser_data->in_source) @@ -2787,7 +2776,7 @@ icon_source_start_element (GMarkupParseContext *context, goto error; } } - + for (i = 0; names[i]; i++) { if (strcmp (names[i], "stock-id") == 0) @@ -2851,7 +2840,7 @@ icon_source_start_element (GMarkupParseContext *context, { gchar *tmp; gint line_number, char_number; - + g_markup_parse_context_get_position (context, &line_number, &char_number); @@ -2865,7 +2854,7 @@ icon_source_start_element (GMarkupParseContext *context, tmp); #else g_warning ("%s", tmp); -#endif +#endif g_free (tmp); g_free (stock_id); g_free (filename); @@ -2909,7 +2898,7 @@ gtk_icon_factory_buildable_custom_tag_end (GtkBuildable *buildable, gpointer *user_data) { GtkIconFactory *icon_factory; - + icon_factory = GTK_ICON_FACTORY (buildable); if (strcmp (tagname, "sources") == 0) diff --git a/gtk/gtkicontheme.c b/gtk/gtkicontheme.c index 6df05ef80e..db183310d7 100644 --- a/gtk/gtkicontheme.c +++ b/gtk/gtkicontheme.c @@ -3508,7 +3508,7 @@ gtk_icon_theme_lookup_by_gicon (GtkIconTheme *icon_theme, * @icon_theme: a #GtkIconTheme * @pixbuf: the pixbuf to wrap in a #GtkIconInfo * - * Creates a #GtkIconInfo for a #GtkPixbuf. + * Creates a #GtkIconInfo for a #GdkPixbuf. * * Returns: a #GtkIconInfo * diff --git a/gtk/gtkiconview.c b/gtk/gtkiconview.c index afbc229222..7bfbaa5573 100644 --- a/gtk/gtkiconview.c +++ b/gtk/gtkiconview.c @@ -46,7 +46,6 @@ #undef DEBUG_ICON_VIEW #define SCROLL_EDGE_SIZE 15 -#define ITEM_PADDING 6 #define GTK_ICON_VIEW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_ICON_VIEW, GtkIconViewPrivate)) @@ -150,6 +149,7 @@ struct _GtkIconViewPrivate gint row_spacing; gint column_spacing; gint margin; + gint item_padding; gint text_column; gint markup_column; @@ -160,8 +160,6 @@ struct _GtkIconViewPrivate gint tooltip_column; - guint draw_focus : 1; - /* Drag-and-drop. */ GdkModifierType start_button_mask; gint pressed_button; @@ -186,7 +184,9 @@ struct _GtkIconViewPrivate guint empty_view_drop :1; guint ctrl_pressed : 1; - guint shift_pressed : 1; + guint shift_pressed : 1; + + guint draw_focus : 1; }; /* Signals */ @@ -220,7 +220,8 @@ enum PROP_COLUMN_SPACING, PROP_MARGIN, PROP_REORDERABLE, - PROP_TOOLTIP_COLUMN + PROP_TOOLTIP_COLUMN, + PROP_ITEM_PADDING }; /* GObject vfuncs */ @@ -714,7 +715,6 @@ gtk_icon_view_class_init (GtkIconViewClass *klass) 0, G_MAXINT, 6, GTK_PARAM_READWRITE)); - /** * GtkIconView:orientation: * @@ -758,6 +758,22 @@ gtk_icon_view_class_init (GtkIconViewClass *klass) -1, GTK_PARAM_READWRITE)); + /** + * GtkIconView:item-padding: + * + * The item-padding property specifies the padding around each + * of the icon view's item. + * + * Since: 2.18 + */ + g_object_class_install_property (gobject_class, + PROP_ITEM_PADDING, + g_param_spec_int ("item-padding", + P_("Item Padding"), + P_("Padding around icon view items"), + 0, G_MAXINT, 6, + GTK_PARAM_READWRITE)); + /* Style properties */ @@ -1106,6 +1122,7 @@ gtk_icon_view_init (GtkIconView *icon_view) icon_view->priv->row_spacing = 6; icon_view->priv->column_spacing = 6; icon_view->priv->margin = 6; + icon_view->priv->item_padding = 6; icon_view->priv->draw_focus = TRUE; } @@ -1216,6 +1233,10 @@ gtk_icon_view_set_property (GObject *object, gtk_icon_view_set_tooltip_column (icon_view, g_value_get_int (value)); break; + case PROP_ITEM_PADDING: + gtk_icon_view_set_item_padding (icon_view, g_value_get_int (value)); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1277,6 +1298,10 @@ gtk_icon_view_get_property (GObject *object, g_value_set_int (value, icon_view->priv->tooltip_column); break; + case PROP_ITEM_PADDING: + g_value_set_int (value, icon_view->priv->item_padding); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1418,10 +1443,10 @@ gtk_icon_view_allocate_children (GtkIconView *icon_view) /* totally ignore our child's requisition */ if (child->cell < 0) { - allocation.x = child->item->x + ITEM_PADDING; - allocation.y = child->item->y + ITEM_PADDING; - allocation.width = child->item->width - ITEM_PADDING * 2; - allocation.height = child->item->height - ITEM_PADDING * 2; + allocation.x = child->item->x + icon_view->priv->item_padding; + allocation.y = child->item->y + icon_view->priv->item_padding; + allocation.width = child->item->width - icon_view->priv->item_padding * 2; + allocation.height = child->item->height - icon_view->priv->item_padding * 2; } else { @@ -2858,16 +2883,16 @@ gtk_icon_view_get_cell_area (GtkIconView *icon_view, if (icon_view->priv->orientation == GTK_ORIENTATION_HORIZONTAL) { cell_area->x = item->box[info->position].x - item->before[info->position]; - cell_area->y = item->y + ITEM_PADDING; + cell_area->y = item->y + icon_view->priv->item_padding; cell_area->width = item->box[info->position].width + item->before[info->position] + item->after[info->position]; - cell_area->height = item->height - ITEM_PADDING * 2; + cell_area->height = item->height - icon_view->priv->item_padding * 2; } else { - cell_area->x = item->x + ITEM_PADDING; + cell_area->x = item->x + icon_view->priv->item_padding; cell_area->y = item->box[info->position].y - item->before[info->position]; - cell_area->width = item->width - ITEM_PADDING * 2; + cell_area->width = item->width - icon_view->priv->item_padding * 2; cell_area->height = item->box[info->position].height + item->before[info->position] + item->after[info->position]; } @@ -2916,19 +2941,16 @@ adjust_wrap_width (GtkIconView *icon_view, else item_width = item->width; - if (item->width == -1) - { - if (item_width > 0) - wrap_width = item_width - pixbuf_width - icon_view->priv->spacing; - else - wrap_width = MAX (2 * pixbuf_width, 50); - } - else if (icon_view->priv->orientation == GTK_ORIENTATION_VERTICAL) - wrap_width = item_width; - else - wrap_width = item_width - pixbuf_width - icon_view->priv->spacing; + if (icon_view->priv->orientation == GTK_ORIENTATION_VERTICAL) + wrap_width = item_width; + else { + if (item->width == -1 && item_width <= 0) + wrap_width = MAX (2 * pixbuf_width, 50); + else + wrap_width = item_width - pixbuf_width - icon_view->priv->spacing; + } - wrap_width -= ITEM_PADDING * 2; + wrap_width -= icon_view->priv->item_padding * 2; g_object_set (text_info->cell, "wrap-width", wrap_width, NULL); g_object_set (text_info->cell, "width", wrap_width, NULL); @@ -2989,8 +3011,8 @@ gtk_icon_view_calculate_item_size (GtkIconView *icon_view, } } - item->width += ITEM_PADDING * 2; - item->height += ITEM_PADDING * 2; + item->width += icon_view->priv->item_padding * 2; + item->height += icon_view->priv->item_padding * 2; } static void @@ -3019,8 +3041,8 @@ gtk_icon_view_calculate_item_size2 (GtkIconView *icon_view, item->height += max_height[i] + (i > 0 ? spacing : 0); } - cell_area.x = item->x + ITEM_PADDING; - cell_area.y = item->y + ITEM_PADDING; + cell_area.x = item->x + icon_view->priv->item_padding; + cell_area.y = item->y + icon_view->priv->item_padding; for (k = 0; k < 2; k++) for (l = icon_view->priv->cell_list, i = 0; l; l = l->next, i++) @@ -3035,7 +3057,7 @@ gtk_icon_view_calculate_item_size2 (GtkIconView *icon_view, if (icon_view->priv->orientation == GTK_ORIENTATION_HORIZONTAL) { - /* We should not subtract ITEM_PADDING from item->height, + /* We should not subtract icon_view->priv->item_padding from item->height, * because item->height is recalculated above using * max_height which does not contain item padding. */ @@ -3047,7 +3069,7 @@ gtk_icon_view_calculate_item_size2 (GtkIconView *icon_view, /* item->width is not recalculated and thus needs to be * corrected for the padding. */ - cell_area.width = item->width - 2 * ITEM_PADDING; + cell_area.width = item->width - 2 * icon_view->priv->item_padding; cell_area.height = max_height[i]; } @@ -3066,9 +3088,9 @@ gtk_icon_view_calculate_item_size2 (GtkIconView *icon_view, } else { - if (item->box[info->position].width > item->width - ITEM_PADDING * 2) + if (item->box[info->position].width > item->width - icon_view->priv->item_padding * 2) { - item->width = item->box[info->position].width + ITEM_PADDING * 2; + item->width = item->box[info->position].width + icon_view->priv->item_padding * 2; cell_area.width = item->width; } item->before[info->position] = item->box[info->position].y - cell_area.y; @@ -3086,7 +3108,7 @@ gtk_icon_view_calculate_item_size2 (GtkIconView *icon_view, } } - item->height += ITEM_PADDING * 2; + item->height += icon_view->priv->item_padding * 2; } static void @@ -3447,6 +3469,9 @@ gtk_icon_view_get_item_at_coords (GtkIconView *icon_view, GList *items, *l; GdkRectangle box; + if (cell_at_pos) + *cell_at_pos = NULL; + for (items = icon_view->priv->items; items; items = items->next) { GtkIconViewItem *item = items->data; @@ -3461,12 +3486,12 @@ gtk_icon_view_get_item_at_coords (GtkIconView *icon_view, for (l = icon_view->priv->cell_list; l; l = l->next) { GtkIconViewCellInfo *info = (GtkIconViewCellInfo *)l->data; - + if (!info->cell->visible) continue; - + gtk_icon_view_get_cell_box (icon_view, item, info, &box); - + if ((x >= box.x && x <= box.x + box.width && y >= box.y && y <= box.y + box.height) || (x >= box.x && @@ -3476,16 +3501,13 @@ gtk_icon_view_get_item_at_coords (GtkIconView *icon_view, { if (cell_at_pos) *cell_at_pos = info; - + return item; } } if (only_in_cell) return NULL; - - if (cell_at_pos) - *cell_at_pos = NULL; } return item; @@ -6242,6 +6264,51 @@ gtk_icon_view_get_margin (GtkIconView *icon_view) return icon_view->priv->margin; } +/** + * gtk_icon_view_set_item_padding: + * @icon_view: a #GtkIconView + * @column_spacing: the item padding + * + * Sets the ::item-padding property which specifies the padding + * around each of the icon view's items. + * + * Since: 2.18 + */ +void +gtk_icon_view_set_item_padding (GtkIconView *icon_view, + gint item_padding) +{ + g_return_if_fail (GTK_IS_ICON_VIEW (icon_view)); + + if (icon_view->priv->item_padding != item_padding) + { + icon_view->priv->item_padding = item_padding; + + gtk_icon_view_stop_editing (icon_view, TRUE); + gtk_icon_view_invalidate_sizes (icon_view); + gtk_icon_view_queue_layout (icon_view); + + g_object_notify (G_OBJECT (icon_view), "item-padding"); + } +} + +/** + * gtk_icon_view_get_item_padding: + * @icon_view: a #GtkIconView + * + * Returns the value of the ::item-padding property. + * + * Return value: the padding around items + * + * Since: 2.18 + */ +gint +gtk_icon_view_get_item_padding (GtkIconView *icon_view) +{ + g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), -1); + + return icon_view->priv->item_padding; +} /* Get/set whether drag_motion requested the drag data and * drag_data_received should thus not actually insert the data, @@ -7158,7 +7225,7 @@ gtk_icon_view_set_drag_dest_item (GtkIconView *icon_view, /* special case a drop on an empty model */ icon_view->priv->empty_view_drop = FALSE; - if (pos == GTK_TREE_VIEW_DROP_BEFORE && path + if (pos == GTK_ICON_VIEW_DROP_ABOVE && path && gtk_tree_path_get_depth (path) == 1 && gtk_tree_path_get_indices (path)[0] == 0) { diff --git a/gtk/gtkiconview.h b/gtk/gtkiconview.h index 65b0588d24..7b9e51d227 100644 --- a/gtk/gtkiconview.h +++ b/gtk/gtkiconview.h @@ -125,6 +125,9 @@ gint gtk_icon_view_get_column_spacing (GtkIconView *icon_view); void gtk_icon_view_set_margin (GtkIconView *icon_view, gint margin); gint gtk_icon_view_get_margin (GtkIconView *icon_view); +void gtk_icon_view_set_item_padding (GtkIconView *icon_view, + gint item_padding); +gint gtk_icon_view_get_item_padding (GtkIconView *icon_view); GtkTreePath * gtk_icon_view_get_path_at_pos (GtkIconView *icon_view, diff --git a/gtk/gtkimagemenuitem.c b/gtk/gtkimagemenuitem.c index 8948c9312a..7f0785d64e 100644 --- a/gtk/gtkimagemenuitem.c +++ b/gtk/gtkimagemenuitem.c @@ -615,7 +615,6 @@ gtk_image_menu_item_update (GtkActivatable *activatable, const gchar *property_name) { GtkImageMenuItem *image_menu_item; - GtkWidget *image; gboolean use_appearance; image_menu_item = GTK_IMAGE_MENU_ITEM (activatable); diff --git a/gtk/gtkimmodule.c b/gtk/gtkimmodule.c index 58ed584116..49eb2abc00 100644 --- a/gtk/gtkimmodule.c +++ b/gtk/gtkimmodule.c @@ -685,17 +685,13 @@ _gtk_im_module_get_default_context_id (GdkWindow *client_window) if (GDK_IS_DRAWABLE (client_window)) { screen = gdk_drawable_get_screen (GDK_DRAWABLE (client_window)); - if (screen) - settings = gtk_settings_get_for_screen (screen); - else - settings = gtk_settings_get_default (); - + settings = gtk_settings_get_for_screen (screen); g_object_get (G_OBJECT (settings), "gtk-im-module", &tmp, NULL); if (tmp) { if (strcmp (tmp, SIMPLE_ID) == 0) context_id = SIMPLE_ID; - else + else { GtkIMModule *module; module = g_hash_table_lookup (contexts_hash, tmp); @@ -704,7 +700,7 @@ _gtk_im_module_get_default_context_id (GdkWindow *client_window) } g_free (tmp); - if (context_id) + if (context_id) return context_id; } } diff --git a/gtk/gtkimmulticontext.c b/gtk/gtkimmulticontext.c index 034582053d..2ec8b32582 100644 --- a/gtk/gtkimmulticontext.c +++ b/gtk/gtkimmulticontext.c @@ -220,23 +220,28 @@ gtk_im_multicontext_set_slave (GtkIMMulticontext *multicontext, g_signal_emit_by_name (multicontext, "preedit-changed"); } +static const gchar * +get_effective_context_id (GtkIMMulticontext *multicontext) +{ + if (multicontext->priv->context_id) + return multicontext->priv->context_id; + + if (!global_context_id) + global_context_id = _gtk_im_module_get_default_context_id (multicontext->priv->client_window); + + return global_context_id; +} + static GtkIMContext * gtk_im_multicontext_get_slave (GtkIMMulticontext *multicontext) { if (!multicontext->slave) { GtkIMContext *slave; - + g_free (multicontext->context_id); - - if (multicontext->priv->context_id) - multicontext->context_id = g_strdup (multicontext->priv->context_id); - else - { - if (!global_context_id) - global_context_id = _gtk_im_module_get_default_context_id (multicontext->priv->client_window); - multicontext->context_id = g_strdup (global_context_id); - } + + multicontext->context_id = g_strdup (get_effective_context_id (multicontext)); slave = _gtk_im_module_create (multicontext->context_id); gtk_im_multicontext_set_slave (multicontext, slave, FALSE); g_object_unref (slave); @@ -264,28 +269,29 @@ gtk_im_multicontext_set_client_window (GtkIMContext *context, multicontext->priv->client_window = window; - gtk_im_multicontext_set_slave (multicontext, NULL, FALSE); - - if (window == NULL) - return; - - screen = gdk_drawable_get_screen (GDK_DRAWABLE (window)); - if (screen) - settings = gtk_settings_get_for_screen (screen); - else - settings = gtk_settings_get_default (); - - connected = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (settings), - "gtk-im-module-connected")); - if (!connected) + if (window) { - g_signal_connect (settings, "notify::gtk-im-module", - G_CALLBACK (im_module_setting_changed), NULL); - g_object_set_data (G_OBJECT (settings), "gtk-im-module-connected", - GINT_TO_POINTER (TRUE)); + screen = gdk_drawable_get_screen (GDK_DRAWABLE (window)); + settings = gtk_settings_get_for_screen (screen); - global_context_id = NULL; + connected = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (settings), + "gtk-im-module-connected")); + if (!connected) + { + g_signal_connect (settings, "notify::gtk-im-module", + G_CALLBACK (im_module_setting_changed), NULL); + g_object_set_data (G_OBJECT (settings), "gtk-im-module-connected", + GINT_TO_POINTER (TRUE)); + + global_context_id = NULL; + } } + + if (g_strcmp0 (multicontext->context_id, get_effective_context_id (multicontext)) != 0) + gtk_im_multicontext_set_slave (multicontext, NULL, FALSE); + + if (multicontext->slave) + gtk_im_context_set_client_window (multicontext->slave, window); } static void @@ -327,16 +333,7 @@ gtk_im_multicontext_focus_in (GtkIMContext *context) GtkIMMulticontext *multicontext = GTK_IM_MULTICONTEXT (context); GtkIMContext *slave; - /* If the global context type is different from the context we were - * using before, get rid of the old slave and create a new one - * for the new global context type. - */ - if (multicontext->context_id == NULL || - (multicontext->priv->context_id != NULL && - strcmp (multicontext->priv->context_id, multicontext->context_id) != 0) || - (multicontext->priv->context_id == NULL && - (global_context_id == NULL || - strcmp (global_context_id, multicontext->context_id) != 0))) + if (g_strcmp0 (multicontext->context_id, get_effective_context_id (multicontext)) != 0) gtk_im_multicontext_set_slave (multicontext, NULL, FALSE); slave = gtk_im_multicontext_get_slave (multicontext); diff --git a/gtk/gtkinfobar.c b/gtk/gtkinfobar.c index 568bd798ef..9ada2c93a3 100644 --- a/gtk/gtkinfobar.c +++ b/gtk/gtkinfobar.c @@ -330,8 +330,8 @@ gtk_info_bar_expose (GtkWidget *widget, detail, widget->allocation.x, widget->allocation.y, - widget->allocation.width + 1, - widget->allocation.height + 1); + widget->allocation.width, + widget->allocation.height); } if (GTK_WIDGET_CLASS (gtk_info_bar_parent_class)->expose_event) @@ -625,6 +625,7 @@ gtk_info_bar_init (GtkInfoBar *info_bar) gtk_box_pack_start (GTK_BOX (info_bar), action_area, FALSE, TRUE, 0); gtk_widget_set_app_paintable (GTK_WIDGET (info_bar), TRUE); + gtk_widget_set_redraw_on_allocate (GTK_WIDGET (info_bar), TRUE); info_bar->priv->content_area = content_area; info_bar->priv->action_area = action_area; diff --git a/gtk/gtkinfobar.h b/gtk/gtkinfobar.h index cbc206a120..530ebfb9ce 100644 --- a/gtk/gtkinfobar.h +++ b/gtk/gtkinfobar.h @@ -28,6 +28,10 @@ * Modified by the GTK+ Team, 2008-2009. */ +#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION) +#error "Only can be included directly." +#endif + #ifndef __GTK_INFO_BAR_H__ #define __GTK_INFO_BAR_H__ diff --git a/gtk/gtkkeyhash.c b/gtk/gtkkeyhash.c index 3de8830ebe..298f94c5d6 100644 --- a/gtk/gtkkeyhash.c +++ b/gtk/gtkkeyhash.c @@ -420,8 +420,8 @@ _gtk_key_hash_lookup (GtkKeyHash *key_hash, xmods = GDK_MOD2_MASK|GDK_MOD3_MASK|GDK_MOD4_MASK|GDK_MOD5_MASK; vmods = GDK_SUPER_MASK|GDK_HYPER_MASK|GDK_META_MASK; - if ((entry->modifiers & ~consumed_modifiers & mask & ~vmods) == (state & ~consumed_modifiers & mask & ~vmods) || - (entry->modifiers & ~consumed_modifiers & mask & ~xmods) == (state & ~consumed_modifiers & mask & ~xmods)) + if ((entry->modifiers & ~consumed_modifiers & mask) == (state & ~consumed_modifiers & mask & ~vmods) || + (entry->modifiers & ~consumed_modifiers & mask) == (state & ~consumed_modifiers & mask & ~xmods)) { gint i; @@ -430,7 +430,7 @@ _gtk_key_hash_lookup (GtkKeyHash *key_hash, GTK_NOTE (KEYBINDINGS, g_message (" found exact match, keyval = %u, modifiers = 0x%04x", entry->keyval, entry->modifiers)); - + if (!have_exact) { g_slist_free (results); diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c index ea963b1853..4577eec3b1 100644 --- a/gtk/gtklabel.c +++ b/gtk/gtklabel.c @@ -147,7 +147,8 @@ enum { PROP_WIDTH_CHARS, PROP_SINGLE_LINE_MODE, PROP_ANGLE, - PROP_MAX_WIDTH_CHARS + PROP_MAX_WIDTH_CHARS, + PROP_TRACK_VISITED_LINKS }; static guint signals[LAST_SIGNAL] = { 0 }; @@ -710,6 +711,23 @@ gtk_label_class_init (GtkLabelClass *class) G_MAXINT, -1, GTK_PARAM_READWRITE)); + + /** + * GtkLabel:track-visited-links: + * + * Set this property to %TRUE to make the label track which links + * have been clicked. It will then apply the ::visited-link-color + * color, instead of ::link-color. + * + * Since: 2.18 + */ + g_object_class_install_property (gobject_class, + PROP_TRACK_VISITED_LINKS, + g_param_spec_boolean ("track-visited-links", + P_("Track visited links"), + P_("Whether visited links should be tracked"), + TRUE, + GTK_PARAM_READWRITE)); /* * Key bindings */ @@ -893,6 +911,9 @@ gtk_label_set_property (GObject *object, case PROP_MAX_WIDTH_CHARS: gtk_label_set_max_width_chars (label, g_value_get_int (value)); break; + case PROP_TRACK_VISITED_LINKS: + gtk_label_set_track_visited_links (label, g_value_get_boolean (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -976,7 +997,9 @@ gtk_label_get_property (GObject *object, case PROP_MAX_WIDTH_CHARS: g_value_set_int (value, gtk_label_get_max_width_chars (label)); break; - + case PROP_TRACK_VISITED_LINKS: + g_value_set_boolean (value, gtk_label_get_track_visited_links (label)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1004,7 +1027,8 @@ gtk_label_init (GtkLabel *label) label->use_underline = FALSE; label->use_markup = FALSE; label->pattern_set = FALSE; - + label->track_links = TRUE; + label->mnemonic_keyval = GDK_VoidSymbol; label->layout = NULL; label->text = NULL; @@ -1012,7 +1036,7 @@ gtk_label_init (GtkLabel *label) label->mnemonic_widget = NULL; label->mnemonic_window = NULL; - + gtk_label_set_text (label, ""); } @@ -1987,7 +2011,8 @@ start_element_handler (GMarkupParseContext *context, return; } - if (pdata->label->select_info) + visited = FALSE; + if (pdata->label->track_links && pdata->label->select_info) { GList *l; for (l = pdata->label->select_info->links; l; l = l->next) @@ -5651,7 +5676,7 @@ emit_activate_link (GtkLabel *label, gboolean handled; g_signal_emit (label, signals[ACTIVATE_LINK], 0, link->uri, &handled); - if (handled && !link->visited) + if (handled && label->track_links && !link->visited) { link->visited = TRUE; /* FIXME: shouldn't have to redo everything here */ @@ -5737,6 +5762,53 @@ gtk_label_get_current_uri (GtkLabel *label) return NULL; } +/** + * gtk_label_set_track_visited_links: + * @label: a #GtkLabel + * @track_links: %TRUE to track visited links + * + * Sets whether the label should keep track of clicked + * links (and use a different color for them). + * + * Since: 2.18 + */ +void +gtk_label_set_track_visited_links (GtkLabel *label, + gboolean track_links) +{ + g_return_if_fail (GTK_IS_LABEL (label)); + + track_links = track_links != FALSE; + + if (label->track_links != track_links) + { + label->track_links = track_links; + + /* FIXME: shouldn't have to redo everything here */ + gtk_label_recalculate (label); + + g_object_notify (G_OBJECT (label), "track-visited-links"); + } +} + +/** + * gtk_label_get_track_visited_links: + * @label: a #GtkLabel + * + * Returns whether the label is currently keeping track + * of clicked links. + * + * Returns: %TRUE if clicked links are remembered + * + * Since: 2.18 + */ +gboolean +gtk_label_get_track_visited_links (GtkLabel *label) +{ + g_return_val_if_fail (GTK_IS_LABEL (label), FALSE); + + return label->track_links; +} static gboolean gtk_label_query_tooltip (GtkWidget *widget, diff --git a/gtk/gtklabel.h b/gtk/gtklabel.h index 3788108eda..d44b142fad 100644 --- a/gtk/gtklabel.h +++ b/gtk/gtklabel.h @@ -67,6 +67,7 @@ struct _GtkLabel guint GSEAL (in_click) : 1; guint GSEAL (wrap_mode) : 3; guint GSEAL (pattern_set) : 1; + guint GSEAL (track_links) : 1; guint GSEAL (mnemonic_keyval); @@ -177,6 +178,9 @@ void gtk_label_set_single_line_mode (GtkLabel *label, gboolean gtk_label_get_single_line_mode (GtkLabel *label); G_CONST_RETURN gchar *gtk_label_get_current_uri (GtkLabel *label); +void gtk_label_set_track_visited_links (GtkLabel *label, + gboolean track_links); +gboolean gtk_label_get_track_visited_links (GtkLabel *label); #ifndef GTK_DISABLE_DEPRECATED diff --git a/gtk/gtkliststore.c b/gtk/gtkliststore.c index 470c9f82b1..8ab1f18fbf 100644 --- a/gtk/gtkliststore.c +++ b/gtk/gtkliststore.c @@ -337,7 +337,6 @@ static void gtk_list_store_set_n_columns (GtkListStore *list_store, gint n_columns) { - GType *new_columns; int i; if (list_store->n_columns == n_columns) @@ -494,10 +493,16 @@ static gboolean gtk_list_store_iter_next (GtkTreeModel *tree_model, GtkTreeIter *iter) { + gboolean retval; + g_return_val_if_fail (GTK_LIST_STORE (tree_model)->stamp == iter->stamp, FALSE); iter->user_data = g_sequence_iter_next (iter->user_data); - return !g_sequence_iter_is_end (iter->user_data); + retval = g_sequence_iter_is_end (iter->user_data); + if (retval) + iter->stamp = 0; + + return !retval; } static gboolean @@ -509,7 +514,10 @@ gtk_list_store_iter_children (GtkTreeModel *tree_model, /* this is a list, nodes have no children */ if (parent) - return FALSE; + { + iter->stamp = 0; + return FALSE; + } if (g_sequence_get_length (list_store->seq) > 0) { @@ -518,7 +526,10 @@ gtk_list_store_iter_children (GtkTreeModel *tree_model, return TRUE; } else - return FALSE; + { + iter->stamp = 0; + return FALSE; + } } static gboolean @@ -551,6 +562,8 @@ gtk_list_store_iter_nth_child (GtkTreeModel *tree_model, GtkListStore *list_store = (GtkListStore *) tree_model; GSequenceIter *child; + iter->stamp = 0; + if (parent) return FALSE; @@ -570,6 +583,7 @@ gtk_list_store_iter_parent (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *child) { + iter->stamp = 0; return FALSE; } diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c index 11aee08fbc..2bbc96d22b 100644 --- a/gtk/gtkmain.c +++ b/gtk/gtkmain.c @@ -686,6 +686,8 @@ do_post_parse_initialization (int *argc, gettext_initialization (); + signal (SIGPIPE, SIG_IGN); + if (g_fatal_warnings) { GLogLevelFlags fatal_mask; @@ -985,6 +987,15 @@ gtk_init_check (int *argc, * the GUI for some reason. If you want your program to fall back to a * textual interface you want to call gtk_init_check() instead. * + * + * + * Since 2.18, GTK+ calls signal (SIGPIPE, SIG_IGN) + * during initialization, to ignore SIGPIPE signals, since these are + * almost never wanted in graphical applications. If you do need to + * handle SIGPIPE for some reason, reset the handler after gtk_init(), + * but notice that other libraries (e.g. libdbus or gvfs) might do + * similar things. + * **/ void gtk_init (int *argc, char ***argv) @@ -1559,7 +1570,15 @@ gtk_main_do_event (GdkEvent *event) gdk_window_end_paint (event->any.window); } else - gtk_widget_send_expose (event_widget, event); + { + /* The app may paint with a previously allocated cairo_t, + which will draw directly to the window. We can't catch cairo + drap operatoins to automatically flush the window, thus we + need to explicitly flush any outstanding moves or double + buffering */ + gdk_window_flush (event->any.window); + gtk_widget_send_expose (event_widget, event); + } break; case GDK_PROPERTY_NOTIFY: diff --git a/gtk/gtkmarshalers.list b/gtk/gtkmarshalers.list index b625cba470..77873cb022 100644 --- a/gtk/gtkmarshalers.list +++ b/gtk/gtkmarshalers.list @@ -107,5 +107,8 @@ VOID:UINT,UINT VOID:UINT,STRING VOID:UINT,BOXED,UINT,FLAGS,FLAGS VOID:UINT,OBJECT,UINT,FLAGS,FLAGS +VOID:UINT,STRING,UINT +VOID:UINT,UINT VOID:VOID OBJECT:OBJECT,INT,INT +VOID:POINTER,POINTER,POINTER,POINTER,STRING diff --git a/gtk/gtkmenu.c b/gtk/gtkmenu.c index 0fd5d3d4ad..5d66878355 100644 --- a/gtk/gtkmenu.c +++ b/gtk/gtkmenu.c @@ -4172,7 +4172,6 @@ gtk_menu_position (GtkMenu *menu) GtkRequisition requisition; GtkMenuPrivate *private; gint x, y; - gboolean initially_pushed_in; gint scroll_offset; gint menu_height; GdkScreen *screen; diff --git a/gtk/gtkmountoperation-stub.c b/gtk/gtkmountoperation-stub.c new file mode 100644 index 0000000000..c7b8d1a9ed --- /dev/null +++ b/gtk/gtkmountoperation-stub.c @@ -0,0 +1,68 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* GTK - The GIMP Toolkit + * Copyright (C) David Zeuthen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GTK+ Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. + */ + +#include "config.h" + +#include +#include "gtkintl.h" + +#include "gtkmountoperationprivate.h" + +GtkMountOperationLookupContext * +_gtk_mount_operation_lookup_context_get (GdkDisplay *display) +{ + return NULL; +} + +void +_gtk_mount_operation_lookup_context_free (GtkMountOperationLookupContext *context) +{ +} + +gboolean +_gtk_mount_operation_lookup_info (GtkMountOperationLookupContext *context, + GPid pid, + gint size_pixels, + gchar **out_name, + gchar **out_command_line, + GdkPixbuf **out_pixbuf) +{ + return FALSE; +} + +gboolean +_gtk_mount_operation_kill_process (GPid pid, + GError **error) +{ + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + _("Cannot kill process with pid %d. Operation is not implemented."), + pid); + return FALSE; +} + diff --git a/gtk/gtkmountoperation-x11.c b/gtk/gtkmountoperation-x11.c new file mode 100644 index 0000000000..a20c8cf428 --- /dev/null +++ b/gtk/gtkmountoperation-x11.c @@ -0,0 +1,972 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* GTK - The GIMP Toolkit + * Copyright (C) David Zeuthen + * Copyright (C) 2001 Havoc Pennington + * Copyright (C) 2005-2007 Vincent Untz + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GTK+ Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. + */ + +#include "config.h" + +#include +#include +#include +#include "x11/gdkx.h" +#include +#include +#include "gtkintl.h" + +/* for the kill(2) system call and errno - POSIX.1-2001 and later */ +#include +#include +#include + +#include "gtkmountoperationprivate.h" + +#include "gtkalias.h" + + +/* ---------------------------------------------------------------------------------------------------- */ +/* these functions are based on code from libwnck (LGPLv2) */ + +static gboolean get_window_list (Display *xdisplay, + Window xwindow, + Atom atom, + Window **windows, + int *len); + +static char* get_utf8_property (Display *xdisplay, + Window xwindow, + Atom atom); + +static gboolean get_cardinal (Display *xdisplay, + Window xwindow, + Atom atom, + int *val); + +static gboolean read_rgb_icon (Display *xdisplay, + Window xwindow, + int ideal_width, + int ideal_height, + int *width, + int *height, + guchar **pixdata); + + +static gboolean +get_cardinal (Display *xdisplay, + Window xwindow, + Atom atom, + int *val) +{ + Atom type; + int format; + gulong nitems; + gulong bytes_after; + gulong *num; + int err, result; + + *val = 0; + + gdk_error_trap_push (); + type = None; + result = XGetWindowProperty (xdisplay, + xwindow, + atom, + 0, G_MAXLONG, + False, XA_CARDINAL, &type, &format, &nitems, + &bytes_after, (void*)&num); + XSync (xdisplay, False); + err = gdk_error_trap_pop (); + + if (err != Success || + result != Success) + return FALSE; + + if (type != XA_CARDINAL) + { + XFree (num); + return FALSE; + } + + *val = *num; + + XFree (num); + + return TRUE; +} + +static char* +get_utf8_property (Display *xdisplay, + Window xwindow, + Atom atom) +{ + Atom type; + int format; + gulong nitems; + gulong bytes_after; + gchar *val; + int err, result; + char *retval; + Atom utf8_string; + + utf8_string = gdk_x11_get_xatom_by_name ("UTF8_STRING"); + + gdk_error_trap_push (); + type = None; + val = NULL; + result = XGetWindowProperty (xdisplay, + xwindow, + atom, + 0, G_MAXLONG, + False, utf8_string, + &type, &format, &nitems, + &bytes_after, (guchar **)&val); + XSync (xdisplay, False); + err = gdk_error_trap_pop (); + + if (err != Success || + result != Success) + return NULL; + + if (type != utf8_string || + format != 8 || + nitems == 0) + { + if (val) + XFree (val); + return NULL; + } + + if (!g_utf8_validate (val, nitems, NULL)) + { + g_warning ("Property %s contained invalid UTF-8\n", + gdk_x11_get_xatom_name (atom)); + XFree (val); + return NULL; + } + + retval = g_strndup (val, nitems); + + XFree (val); + + return retval; +} + +static gboolean +find_largest_sizes (gulong *data, + gulong nitems, + int *width, + int *height) +{ + *width = 0; + *height = 0; + + while (nitems > 0) + { + int w, h; + gboolean replace; + + replace = FALSE; + + if (nitems < 3) + return FALSE; /* no space for w, h */ + + w = data[0]; + h = data[1]; + + if (nitems < ((w * h) + 2)) + return FALSE; /* not enough data */ + + *width = MAX (w, *width); + *height = MAX (h, *height); + + data += (w * h) + 2; + nitems -= (w * h) + 2; + } + + return TRUE; +} + +static gboolean +find_best_size (gulong *data, + gulong nitems, + int ideal_width, + int ideal_height, + int *width, + int *height, + gulong **start) +{ + int best_w; + int best_h; + gulong *best_start; + int max_width, max_height; + + *width = 0; + *height = 0; + *start = NULL; + + if (!find_largest_sizes (data, nitems, &max_width, &max_height)) + return FALSE; + + if (ideal_width < 0) + ideal_width = max_width; + if (ideal_height < 0) + ideal_height = max_height; + + best_w = 0; + best_h = 0; + best_start = NULL; + + while (nitems > 0) + { + int w, h; + gboolean replace; + + replace = FALSE; + + if (nitems < 3) + return FALSE; /* no space for w, h */ + + w = data[0]; + h = data[1]; + + if (nitems < ((w * h) + 2)) + break; /* not enough data */ + + if (best_start == NULL) + { + replace = TRUE; + } + else + { + /* work with averages */ + const int ideal_size = (ideal_width + ideal_height) / 2; + int best_size = (best_w + best_h) / 2; + int this_size = (w + h) / 2; + + /* larger than desired is always better than smaller */ + if (best_size < ideal_size && + this_size >= ideal_size) + replace = TRUE; + /* if we have too small, pick anything bigger */ + else if (best_size < ideal_size && + this_size > best_size) + replace = TRUE; + /* if we have too large, pick anything smaller + * but still >= the ideal + */ + else if (best_size > ideal_size && + this_size >= ideal_size && + this_size < best_size) + replace = TRUE; + } + + if (replace) + { + best_start = data + 2; + best_w = w; + best_h = h; + } + + data += (w * h) + 2; + nitems -= (w * h) + 2; + } + + if (best_start) + { + *start = best_start; + *width = best_w; + *height = best_h; + return TRUE; + } + else + return FALSE; +} + +static void +argbdata_to_pixdata (gulong *argb_data, + int len, + guchar **pixdata) +{ + guchar *p; + int i; + + *pixdata = g_new (guchar, len * 4); + p = *pixdata; + + /* One could speed this up a lot. */ + i = 0; + while (i < len) + { + guint argb; + guint rgba; + + argb = argb_data[i]; + rgba = (argb << 8) | (argb >> 24); + + *p = rgba >> 24; + ++p; + *p = (rgba >> 16) & 0xff; + ++p; + *p = (rgba >> 8) & 0xff; + ++p; + *p = rgba & 0xff; + ++p; + + ++i; + } +} + +static gboolean +read_rgb_icon (Display *xdisplay, + Window xwindow, + int ideal_width, + int ideal_height, + int *width, + int *height, + guchar **pixdata) +{ + Atom type; + int format; + gulong nitems; + gulong bytes_after; + int result, err; + gulong *data; + gulong *best; + int w, h; + + gdk_error_trap_push (); + type = None; + data = NULL; + result = XGetWindowProperty (xdisplay, + xwindow, + gdk_x11_get_xatom_by_name ("_NET_WM_ICON"), + 0, G_MAXLONG, + False, XA_CARDINAL, &type, &format, &nitems, + &bytes_after, (void*)&data); + + XSync (xdisplay, False); + err = gdk_error_trap_pop (); + + if (err != Success || + result != Success) + return FALSE; + + if (type != XA_CARDINAL) + { + XFree (data); + return FALSE; + } + + if (!find_best_size (data, nitems, + ideal_width, ideal_height, + &w, &h, &best)) + { + XFree (data); + return FALSE; + } + + *width = w; + *height = h; + + argbdata_to_pixdata (best, w * h, pixdata); + + XFree (data); + + return TRUE; +} + +static void +free_pixels (guchar *pixels, gpointer data) +{ + g_free (pixels); +} + +static GdkPixbuf* +scaled_from_pixdata (guchar *pixdata, + int w, + int h, + int new_w, + int new_h) +{ + GdkPixbuf *src; + GdkPixbuf *dest; + + src = gdk_pixbuf_new_from_data (pixdata, + GDK_COLORSPACE_RGB, + TRUE, + 8, + w, h, w * 4, + free_pixels, + NULL); + + if (src == NULL) + return NULL; + + if (w != h) + { + GdkPixbuf *tmp; + int size; + + size = MAX (w, h); + + tmp = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, size, size); + + if (tmp != NULL) + { + gdk_pixbuf_fill (tmp, 0); + gdk_pixbuf_copy_area (src, 0, 0, w, h, + tmp, + (size - w) / 2, (size - h) / 2); + + g_object_unref (src); + src = tmp; + } + } + + if (w != new_w || h != new_h) + { + dest = gdk_pixbuf_scale_simple (src, new_w, new_h, GDK_INTERP_BILINEAR); + + g_object_unref (G_OBJECT (src)); + } + else + { + dest = src; + } + + return dest; +} + +static gboolean +get_window_list (Display *xdisplay, + Window xwindow, + Atom atom, + Window **windows, + int *len) +{ + Atom type; + int format; + gulong nitems; + gulong bytes_after; + Window *data; + int err, result; + + *windows = NULL; + *len = 0; + + gdk_error_trap_push (); + type = None; + result = XGetWindowProperty (xdisplay, + xwindow, + atom, + 0, G_MAXLONG, + False, XA_WINDOW, &type, &format, &nitems, + &bytes_after, (void*)&data); + XSync (xdisplay, False); + err = gdk_error_trap_pop (); + + if (err != Success || + result != Success) + return FALSE; + + if (type != XA_WINDOW) + { + XFree (data); + return FALSE; + } + + *windows = g_new (Window, nitems); + memcpy (*windows, data, sizeof (Window) * nitems); + *len = nitems; + + XFree (data); + + return TRUE; +} + + +/* ---------------------------------------------------------------------------------------------------- */ + +struct _GtkMountOperationLookupContext +{ + /* Hash from pid (gint) -> XID (gint) + * + * Note that XIDs are at most 27 bits - however, also note that sizeof(XID) == 8 on + * x86_64 - that's just xlib brokenness. So it's safe to stuff the XID into a pointer. + */ + GHashTable *pid_to_window; + GdkDisplay *display; +}; + +GtkMountOperationLookupContext * +_gtk_mount_operation_lookup_context_get (GdkDisplay *display) +{ + GtkMountOperationLookupContext *context; + Window *mapping; + gint mapping_length; + gint n; + + context = g_new0 (GtkMountOperationLookupContext, 1); + + context->pid_to_window = g_hash_table_new (g_direct_hash, g_direct_equal); + context->display = display; + + mapping = NULL; + mapping_length = 0; + get_window_list (GDK_DISPLAY_XDISPLAY (context->display), + GDK_ROOT_WINDOW(), + gdk_x11_get_xatom_by_name_for_display (context->display, + "_NET_CLIENT_LIST"), + &mapping, + &mapping_length); + for (n = 0; n < mapping_length; n++) + { + gint pid; + + if (!get_cardinal (GDK_DISPLAY_XDISPLAY (context->display), + mapping[n], + gdk_x11_get_xatom_by_name_for_display (context->display, + "_NET_WM_PID"), + &pid)) + continue; + + g_hash_table_insert (context->pid_to_window, + GINT_TO_POINTER (pid), + GINT_TO_POINTER ((gint) mapping[n])); + } + g_free (mapping); + + return context; +} + +void +_gtk_mount_operation_lookup_context_free (GtkMountOperationLookupContext *context) +{ + g_hash_table_unref (context->pid_to_window); + g_free (context); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +#ifdef __linux__ + +static GPid +pid_get_parent (GPid pid) +{ + GPid ppid; + gchar **tokens; + gchar *stat_filename; + gchar *stat_contents; + gsize stat_len; + + ppid = 0; + tokens = NULL; + stat_contents = NULL; + stat_filename = NULL; + + /* fail if trying to get the parent of the init process (no such thing) */ + if (pid == 1) + goto out; + + stat_filename = g_strdup_printf ("/proc/%d/status", pid); + if (g_file_get_contents (stat_filename, + &stat_contents, + &stat_len, + NULL)) + { + guint n; + + tokens = g_strsplit (stat_contents, "\n", 0); + + for (n = 0; tokens[n] != NULL; n++) + { + if (g_str_has_prefix (tokens[n], "PPid:")) + { + gchar *endp; + + endp = NULL; + ppid = strtoll (tokens[n] + sizeof "PPid:" - 1, &endp, 10); + if (endp == NULL || *endp != '\0') + { + g_warning ("Error parsing contents of `%s'. Parent pid is malformed.", + stat_filename); + ppid = 0; + goto out; + } + + break; + } + } + } + + out: + g_strfreev (tokens); + g_free (stat_contents); + g_free (stat_filename); + + return ppid; +} + +static gchar * +pid_get_env (GPid pid, + const gchar *key) +{ + gchar *ret; + gchar *env_filename; + gchar *env; + gsize env_len; + gsize key_len; + gchar *end; + + ret = NULL; + + key_len = strlen (key); + + env_filename = g_strdup_printf ("/proc/%d/environ", pid); + if (g_file_get_contents (env_filename, + &env, + &env_len, + NULL)) + { + guint n; + + /* /proc//environ in Linux is split at '\0' points, g_strsplit() can't handle that... */ + n = 0; + while (TRUE) + { + if (env[n] == '\0' || n >= env_len) + break; + + if (g_str_has_prefix (env + n, key) && (*(env + n + key_len) == '=')) + { + ret = g_strdup (env + n + key_len + 1); + + /* skip invalid UTF-8 */ + if (!g_utf8_validate (ret, -1, (const gchar **) &end)) + *end = '\0'; + break; + } + + for (; env[n] != '\0' && n < env_len; n++) + ; + n++; + } + g_free (env); + } + g_free (env_filename); + + return ret; +} + +static gchar * +pid_get_command_line (GPid pid) +{ + gchar *cmdline_filename; + gchar *cmdline_contents; + gsize cmdline_len; + guint n; + gchar *end; + + cmdline_contents = NULL; + + cmdline_filename = g_strdup_printf ("/proc/%d/cmdline", pid); + if (!g_file_get_contents (cmdline_filename, + &cmdline_contents, + &cmdline_len, + NULL)) + goto out; + + /* /proc//cmdline separates args by NUL-bytes - replace with spaces */ + for (n = 0; n < cmdline_len - 1; n++) + { + if (cmdline_contents[n] == '\0') + cmdline_contents[n] = ' '; + } + + /* skip invalid UTF-8 */ + if (!g_utf8_validate (cmdline_contents, -1, (const gchar **) &end)) + *end = '\0'; + + out: + g_free (cmdline_filename); + + return cmdline_contents; +} + +/* ---------------------------------------------------------------------------------------------------- */ +#else + +/* TODO: please implement for your OS - must return valid UTF-8 */ + +static GPid +pid_get_parent (GPid pid) +{ + return 0; +} + +static gchar * +pid_get_env (GPid pid, + const gchar *key) +{ + return NULL; +} + +static gchar * +pid_get_command_line (GPid pid) +{ + return NULL; +} + +#endif + +/* ---------------------------------------------------------------------------------------------------- */ + +static gchar * +get_name_for_window_with_pid (GtkMountOperationLookupContext *context, + GPid pid) +{ + Window window; + Window windowid_window; + gchar *ret; + + ret = NULL; + + window = GPOINTER_TO_INT (g_hash_table_lookup (context->pid_to_window, GINT_TO_POINTER (pid))); + if (window == None) + { + gchar *windowid_value; + + /* check for $WINDOWID (set by terminals) and see if we can get the title that way */ + windowid_value = pid_get_env (pid, "WINDOWID"); + if (windowid_value != NULL) + { + gchar *endp; + + endp = NULL; + windowid_window = (Window) g_ascii_strtoll (windowid_value, &endp, 10); + if (endp != NULL || *endp == '\0') + { + window = windowid_window; + } + g_free (windowid_value); + } + + /* otherwise, check for parents */ + if (window == None) + { + do + { + pid = pid_get_parent (pid); + if (pid == 0) + break; + + window = GPOINTER_TO_INT (g_hash_table_lookup (context->pid_to_window, GINT_TO_POINTER (pid))); + if (window != None) + break; + } + while (TRUE); + } + } + + if (window != None) + { + ret = get_utf8_property (GDK_DISPLAY_XDISPLAY (context->display), + window, + gdk_x11_get_xatom_by_name_for_display (context->display, + "_NET_WM_NAME")); + if (ret == NULL) + ret = get_utf8_property (GDK_DISPLAY_XDISPLAY (context->display), + window, gdk_x11_get_xatom_by_name_for_display (context->display, + "_NET_WM_ICON_NAME")); + } + + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static GdkPixbuf * +get_pixbuf_for_window_with_pid (GtkMountOperationLookupContext *context, + GPid pid, + gint size_pixels) +{ + Window window; + GdkPixbuf *ret; + + ret = NULL; + + window = GPOINTER_TO_INT (g_hash_table_lookup (context->pid_to_window, GINT_TO_POINTER (pid))); + if (window == None) + { + /* otherwise, check for parents */ + do + { + pid = pid_get_parent (pid); + if (pid == 0) + break; + + window = GPOINTER_TO_INT (g_hash_table_lookup (context->pid_to_window, GINT_TO_POINTER (pid))); + if (window != None) + break; + } + while (TRUE); + } + + if (window != None) + { + gint width; + gint height; + guchar *pixdata; + + if (read_rgb_icon (GDK_DISPLAY_XDISPLAY (context->display), + window, + size_pixels, size_pixels, + &width, &height, + &pixdata)) + { + /* steals pixdata */ + ret = scaled_from_pixdata (pixdata, + width, height, + size_pixels, size_pixels); + } + } + + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static const gchar *well_known_commands[] = +{ + /* translators: this string is a name for the 'less' command */ + "less", N_("Terminal Pager"), + "top", N_("Top Command"), + "bash", N_("Bourne Again Shell"), + "sh", N_("Bourne Shell"), + "zsh", N_("Z Shell"), + NULL, +}; + +gboolean +_gtk_mount_operation_lookup_info (GtkMountOperationLookupContext *context, + GPid pid, + gint size_pixels, + gchar **out_name, + gchar **out_command_line, + GdkPixbuf **out_pixbuf) +{ + g_return_val_if_fail (out_name != NULL && *out_name == NULL, FALSE); + g_return_val_if_fail (out_command_line != NULL && *out_command_line == NULL, FALSE); + g_return_val_if_fail (out_pixbuf != NULL && *out_pixbuf == NULL, FALSE); + + /* We perform two different lookups for name and icon size.. this is + * because we want the name from the window with WINDOWID and this + * normally does not give you an icon + * + * (the canonical example is a tab in gnome-terminal - the shell/command running + * in the shell will have WINDOWID set - but this window won't have an icon - so + * we want to continue up until the gnome-terminal window so we can get that icon) + */ + + *out_command_line = pid_get_command_line (pid); + + *out_name = get_name_for_window_with_pid (context, pid); + + *out_pixbuf = get_pixbuf_for_window_with_pid (context, pid, size_pixels); + + /* if we didn't manage to find the name via X, fall back to the basename + * of the first element of the command line and, for maximum geek-comfort, + * map a few well-known commands to proper translated names + */ + if (*out_name == NULL && *out_command_line != NULL && + strlen (*out_command_line) > 0 && (*out_command_line)[0] != ' ') + { + guint n; + gchar *s; + gchar *p; + + /* find the first character after the first argument */ + s = strchr (*out_command_line, ' '); + if (s == NULL) + s = *out_command_line + strlen (*out_command_line); + + for (p = s; p > *out_command_line; p--) + { + if (*p == '/') + { + p++; + break; + } + } + + *out_name = g_strndup (p, s - p); + + for (n = 0; well_known_commands[n] != NULL; n += 2) + { + /* sometimes the command is prefixed with a -, e.g. '-bash' instead + * of 'bash' - handle that as well + */ + if ((strcmp (well_known_commands[n], *out_name) == 0) || + ((*out_name)[0] == '-' && (strcmp (well_known_commands[n], (*out_name) + 1) == 0))) + { + g_free (*out_name); + *out_name = g_strdup (_(well_known_commands[n+1])); + break; + } + } + } + + return TRUE; +} + +gboolean +_gtk_mount_operation_kill_process (GPid pid, + GError **error) +{ + gboolean ret; + + ret = TRUE; + + if (kill ((pid_t) pid, SIGTERM) != 0) + { + int errsv = errno; + + /* TODO: On EPERM, we could use a setuid helper using polkit (very easy to implement + * via pkexec(1)) to allow the user to e.g. authenticate to gain the authorization + * to kill the process. But that's not how things currently work. + */ + + ret = FALSE; + g_set_error (error, + G_IO_ERROR, + g_io_error_from_errno (errsv), + _("Cannot end process with pid %d: %s"), + pid, + g_strerror (errsv)); + } + + return ret; +} diff --git a/gtk/gtkmountoperation.c b/gtk/gtkmountoperation.c index ace58ed90a..6137388c0b 100644 --- a/gtk/gtkmountoperation.c +++ b/gtk/gtkmountoperation.c @@ -29,6 +29,7 @@ #include +#include "gtkmountoperationprivate.h" #include "gtkalignment.h" #include "gtkbox.h" #include "gtkentry.h" @@ -44,6 +45,14 @@ #include "gtkstock.h" #include "gtktable.h" #include "gtkwindow.h" +#include "gtktreeview.h" +#include "gtktreeselection.h" +#include "gtkcellrenderertext.h" +#include "gtkcellrendererpixbuf.h" +#include "gtkscrolledwindow.h" +#include "gtkicontheme.h" +#include "gtkimagemenuitem.h" +#include "gtkmain.h" #include "gtkalias.h" /** @@ -58,14 +67,16 @@ * applications. */ -/** +/** * GtkMountOperation: * - * #GtkMountOperation is an implementation of #GMountOperation that + * #GtkMountOperation is an implementation of #GMountOperation that * can be used with GIO functions for mounting volumes such as - * g_file_mount_enclosing_volume() or g_file_mount_mountable(). + * g_file_mount_enclosing_volume(), g_file_mount_mountable(), + * g_volume_mount(), g_mount_unmount() and others. * - * When necessary, #GtkMountOperation shows dialogs to ask for passwords. + * When necessary, #GtkMountOperation shows dialogs to ask for + * passwords, questions or show processes blocking unmount. */ static void gtk_mount_operation_finalize (GObject *object); @@ -88,6 +99,11 @@ static void gtk_mount_operation_ask_question (GMountOperation *op, const char *message, const char *choices[]); +static void gtk_mount_operation_show_processes (GMountOperation *op, + const char *message, + GArray *processes, + const char *choices[]); + static void gtk_mount_operation_aborted (GMountOperation *op); G_DEFINE_TYPE (GtkMountOperation, gtk_mount_operation, G_TYPE_MOUNT_OPERATION); @@ -115,6 +131,10 @@ struct _GtkMountOperationPrivate { GAskPasswordFlags ask_flags; GPasswordSave password_save; gboolean anonymous; + + /* for the show-processes dialog */ + GtkWidget *process_tree_view; + GtkListStore *process_list_store; }; static void @@ -131,6 +151,7 @@ gtk_mount_operation_class_init (GtkMountOperationClass *klass) mount_op_class->ask_password = gtk_mount_operation_ask_password; mount_op_class->ask_question = gtk_mount_operation_ask_question; + mount_op_class->show_processes = gtk_mount_operation_show_processes; mount_op_class->aborted = gtk_mount_operation_aborted; g_object_class_install_property (object_class, @@ -747,6 +768,578 @@ gtk_mount_operation_ask_question (GMountOperation *op, g_object_ref (op); } +static void +show_processes_button_clicked (GtkDialog *dialog, + gint button_number, + GMountOperation *op) +{ + GtkMountOperationPrivate *priv; + GtkMountOperation *operation; + + operation = GTK_MOUNT_OPERATION (op); + priv = operation->priv; + + if (button_number >= 0) + { + g_mount_operation_set_choice (op, button_number); + g_mount_operation_reply (op, G_MOUNT_OPERATION_HANDLED); + } + else + g_mount_operation_reply (op, G_MOUNT_OPERATION_ABORTED); + + priv->dialog = NULL; + g_object_notify (G_OBJECT (operation), "is-showing"); + gtk_widget_destroy (GTK_WIDGET (dialog)); + g_object_unref (op); +} + +static gint +pid_equal (gconstpointer a, + gconstpointer b) +{ + GPid pa, pb; + + pa = *((GPid *) a); + pb = *((GPid *) b); + + return GPOINTER_TO_INT(pb) - GPOINTER_TO_INT(pa); +} + +static void +diff_sorted_arrays (GArray *array1, + GArray *array2, + GCompareFunc compare, + GArray *added_indices, + GArray *removed_indices) +{ + gint order; + guint n1, n2; + guint elem_size; + + n1 = n2 = 0; + + elem_size = g_array_get_element_size (array1); + g_assert (elem_size == g_array_get_element_size (array2)); + + while (n1 < array1->len && n2 < array2->len) + { + order = (*compare) (((const char*) array1->data) + n1 * elem_size, + ((const char*) array2->data) + n2 * elem_size); + if (order < 0) + { + g_array_append_val (removed_indices, n1); + n1++; + } + else if (order > 0) + { + g_array_append_val (added_indices, n2); + n2++; + } + else + { /* same item */ + n1++; + n2++; + } + } + + while (n1 < array1->len) + { + g_array_append_val (removed_indices, n1); + n1++; + } + while (n2 < array2->len) + { + g_array_append_val (added_indices, n2); + n2++; + } +} + + +static void +add_pid_to_process_list_store (GtkMountOperation *mount_operation, + GtkMountOperationLookupContext *lookup_context, + GtkListStore *list_store, + GPid pid) +{ + gchar *command_line; + gchar *name; + GdkPixbuf *pixbuf; + gchar *markup; + GtkTreeIter iter; + + name = NULL; + pixbuf = NULL; + command_line = NULL; + _gtk_mount_operation_lookup_info (lookup_context, + pid, + 24, + &name, + &command_line, + &pixbuf); + + if (name == NULL) + name = g_strdup_printf (_("Unknown Application (pid %d)"), pid); + + if (command_line == NULL) + command_line = g_strdup (""); + + if (pixbuf == NULL) + { + GtkIconTheme *theme; + theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (mount_operation->priv->dialog))); + pixbuf = gtk_icon_theme_load_icon (theme, + "application-x-executable", + 24, + 0, + NULL); + } + + markup = g_strdup_printf ("%s\n" + "%s", + name, + command_line); + + gtk_list_store_append (list_store, &iter); + gtk_list_store_set (list_store, &iter, + 0, pixbuf, + 1, markup, + 2, pid, + -1); + + if (pixbuf != NULL) + g_object_unref (pixbuf); + g_free (markup); + g_free (name); + g_free (command_line); +} + +static void +remove_pid_from_process_list_store (GtkMountOperation *mount_operation, + GtkListStore *list_store, + GPid pid) +{ + GtkTreeIter iter; + GPid pid_of_item; + + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (list_store), &iter)) + { + do + { + gtk_tree_model_get (GTK_TREE_MODEL (list_store), + &iter, + 2, &pid_of_item, + -1); + + if (pid_of_item == pid) + { + gtk_list_store_remove (list_store, &iter); + break; + } + } + while (gtk_tree_model_iter_next (GTK_TREE_MODEL (list_store), &iter)); + } +} + + +static void +update_process_list_store (GtkMountOperation *mount_operation, + GtkListStore *list_store, + GArray *processes) +{ + guint n; + GtkMountOperationLookupContext *lookup_context; + GArray *current_pids; + GArray *pid_indices_to_add; + GArray *pid_indices_to_remove; + GtkTreeIter iter; + GPid pid; + + /* Just removing all items and adding new ones will screw up the + * focus handling in the treeview - so compute the delta, and add/remove + * items as appropriate + */ + current_pids = g_array_new (FALSE, FALSE, sizeof (GPid)); + pid_indices_to_add = g_array_new (FALSE, FALSE, sizeof (gint)); + pid_indices_to_remove = g_array_new (FALSE, FALSE, sizeof (gint)); + + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (list_store), &iter)) + { + do + { + gtk_tree_model_get (GTK_TREE_MODEL (list_store), + &iter, + 2, &pid, + -1); + + g_array_append_val (current_pids, pid); + } + while (gtk_tree_model_iter_next (GTK_TREE_MODEL (list_store), &iter)); + } + + g_array_sort (current_pids, pid_equal); + g_array_sort (processes, pid_equal); + + diff_sorted_arrays (current_pids, processes, pid_equal, pid_indices_to_add, pid_indices_to_remove); + + if (pid_indices_to_add->len > 0) + lookup_context = _gtk_mount_operation_lookup_context_get (gtk_widget_get_display (mount_operation->priv->process_tree_view)); + for (n = 0; n < pid_indices_to_add->len; n++) + { + pid = g_array_index (processes, GPid, n); + add_pid_to_process_list_store (mount_operation, lookup_context, list_store, pid); + } + + for (n = 0; n < pid_indices_to_remove->len; n++) + { + pid = g_array_index (current_pids, GPid, n); + remove_pid_from_process_list_store (mount_operation, list_store, pid); + } + if (pid_indices_to_add->len > 0) + _gtk_mount_operation_lookup_context_free (lookup_context); + + /* select the first item, if we went from a zero to a non-zero amount of processes */ + if (current_pids->len == 0 && pid_indices_to_add->len > 0) + { + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (list_store), &iter)) + { + GtkTreeSelection *tree_selection; + tree_selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (mount_operation->priv->process_tree_view)); + gtk_tree_selection_select_iter (tree_selection, &iter); + } + } + + g_array_unref (current_pids); + g_array_unref (pid_indices_to_add); + g_array_unref (pid_indices_to_remove); +} + +static void +on_end_process_activated (GtkMenuItem *item, + gpointer user_data) +{ + GtkMountOperation *op = GTK_MOUNT_OPERATION (user_data); + GtkTreeSelection *selection; + GtkTreeIter iter; + GPid pid_to_kill; + GError *error; + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (op->priv->process_tree_view)); + + if (!gtk_tree_selection_get_selected (selection, + NULL, + &iter)) + goto out; + + gtk_tree_model_get (GTK_TREE_MODEL (op->priv->process_list_store), + &iter, + 2, &pid_to_kill, + -1); + + /* TODO: We might want to either + * + * - Be smart about things and send SIGKILL rather than SIGTERM if + * this is the second time the user requests killing a process + * + * - Or, easier (but worse user experience), offer both "End Process" + * and "Terminate Process" options + * + * But that's not how things work right now.... + */ + error = NULL; + if (!_gtk_mount_operation_kill_process (pid_to_kill, &error)) + { + GtkWidget *dialog; + gint response; + + /* Use GTK_DIALOG_DESTROY_WITH_PARENT here since the parent dialog can be + * indeed be destroyed via the GMountOperation::abort signal... for example, + * this is triggered if the user yanks the device while we are showing + * the dialog... + */ + dialog = gtk_message_dialog_new (GTK_WINDOW (op->priv->dialog), + GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + _("Unable to end process")); + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), + "%s", + error->message); + + gtk_widget_show_all (dialog); + response = gtk_dialog_run (GTK_DIALOG (dialog)); + + /* GTK_RESPONSE_NONE means the dialog were programmatically destroy, e.g. that + * GTK_DIALOG_DESTROY_WITH_PARENT kicked in - so it would trigger a warning to + * destroy the dialog in that case + */ + if (response != GTK_RESPONSE_NONE) + gtk_widget_destroy (dialog); + + g_error_free (error); + } + + out: + ; +} + +static gboolean +do_popup_menu_for_process_tree_view (GtkWidget *widget, + GdkEventButton *event, + GtkMountOperation *op) +{ + GtkWidget *menu; + GtkWidget *item; + gint button; + gint event_time; + gboolean popped_up_menu; + + popped_up_menu = FALSE; + + menu = gtk_menu_new (); + + item = gtk_image_menu_item_new_with_mnemonic (_("_End Process")); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), + gtk_image_new_from_stock (GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU)); + g_signal_connect (item, "activate", + G_CALLBACK (on_end_process_activated), + op); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + gtk_widget_show_all (menu); + + if (event != NULL) + { + GtkTreePath *path; + GtkTreeSelection *selection; + + if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (op->priv->process_tree_view), + (gint) event->x, + (gint) event->y, + &path, + NULL, + NULL, + NULL)) + { + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (op->priv->process_tree_view)); + gtk_tree_selection_select_path (selection, path); + gtk_tree_path_free (path); + } + else + { + /* don't popup a menu if the user right-clicked in an area with no rows */ + goto out; + } + + button = event->button; + event_time = event->time; + } + else + { + button = 0; + event_time = gtk_get_current_event_time (); + } + + gtk_menu_popup (GTK_MENU (menu), + NULL, + widget, + NULL, + NULL, + button, + event_time); + + popped_up_menu = TRUE; + + out: + return popped_up_menu; +} + +static gboolean +on_popup_menu_for_process_tree_view (GtkWidget *widget, + gpointer user_data) +{ + GtkMountOperation *op = GTK_MOUNT_OPERATION (user_data); + return do_popup_menu_for_process_tree_view (widget, NULL, op); +} + +static gboolean +on_button_press_event_for_process_tree_view (GtkWidget *widget, + GdkEventButton *event, + gpointer user_data) +{ + GtkMountOperation *op = GTK_MOUNT_OPERATION (user_data); + gboolean ret; + + ret = FALSE; + + /* Ignore double-clicks and triple-clicks */ + if (event->button == 3 && event->type == GDK_BUTTON_PRESS) + { + ret = do_popup_menu_for_process_tree_view (widget, event, op); + } + + return ret; +} + +static void +create_show_processes_dialog (GMountOperation *op, + const char *message, + const char *choices[]) +{ + GtkMountOperationPrivate *priv; + GtkWidget *dialog; + const char *secondary = NULL; + char *primary; + int count, len = 0; + GtkWidget *label; + GtkWidget *tree_view; + GtkWidget *scrolled_window; + GtkWidget *vbox; + GtkWidget *content_area; + GtkTreeViewColumn *column; + GtkCellRenderer *renderer; + GtkListStore *list_store; + gchar *s; + + priv = GTK_MOUNT_OPERATION (op)->priv; + + primary = strstr (message, "\n"); + if (primary) + { + secondary = primary + 1; + primary = g_strndup (message, primary - message); + } + + dialog = gtk_dialog_new (); + + if (priv->parent_window != NULL) + gtk_window_set_transient_for (GTK_WINDOW (dialog), priv->parent_window); + gtk_window_set_title (GTK_WINDOW (dialog), ""); + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); + + content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog)); + vbox = gtk_vbox_new (FALSE, 12); + gtk_container_set_border_width (GTK_CONTAINER (vbox), 12); + gtk_box_pack_start (GTK_BOX (content_area), vbox, TRUE, TRUE, 0); + + if (secondary != NULL) + { + s = g_strdup_printf ("%s\n\n%s", primary, secondary); + } + else + { + s = g_strdup_printf ("%s", primary); + } + g_free (primary); + label = gtk_label_new (NULL); + gtk_label_set_markup (GTK_LABEL (label), s); + g_free (s); + gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0); + + /* First count the items in the list then + * add the buttons in reverse order */ + + while (choices[len] != NULL) + len++; + + for (count = len - 1; count >= 0; count--) + gtk_dialog_add_button (GTK_DIALOG (dialog), choices[count], count); + + g_signal_connect (G_OBJECT (dialog), "response", + G_CALLBACK (show_processes_button_clicked), op); + + priv->dialog = GTK_DIALOG (dialog); + g_object_notify (G_OBJECT (op), "is-showing"); + + if (priv->parent_window == NULL && priv->screen) + gtk_window_set_screen (GTK_WINDOW (dialog), priv->screen); + + tree_view = gtk_tree_view_new (); + /* TODO: should use EM's when gtk+ RI patches land */ + gtk_widget_set_size_request (tree_view, + 300, + 120); + + column = gtk_tree_view_column_new (); + renderer = gtk_cell_renderer_pixbuf_new (); + gtk_tree_view_column_pack_start (column, renderer, FALSE); + gtk_tree_view_column_set_attributes (column, renderer, + "pixbuf", 0, + NULL); + renderer = gtk_cell_renderer_text_new (); + g_object_set (renderer, + "ellipsize", PANGO_ELLIPSIZE_MIDDLE, + "ellipsize-set", TRUE, + NULL); + gtk_tree_view_column_pack_start (column, renderer, TRUE); + gtk_tree_view_column_set_attributes (column, renderer, + "markup", 1, + NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column); + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (tree_view), FALSE); + + + scrolled_window = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), + GTK_POLICY_NEVER, + GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_IN); + + gtk_container_add (GTK_CONTAINER (scrolled_window), tree_view); + gtk_box_pack_start (GTK_BOX (vbox), scrolled_window, TRUE, TRUE, 0); + + g_signal_connect (tree_view, "popup-menu", + G_CALLBACK (on_popup_menu_for_process_tree_view), + op); + g_signal_connect (tree_view, "button-press-event", + G_CALLBACK (on_button_press_event_for_process_tree_view), + op); + + list_store = gtk_list_store_new (3, + GDK_TYPE_PIXBUF, + G_TYPE_STRING, + G_TYPE_INT); + + gtk_tree_view_set_model (GTK_TREE_VIEW (tree_view), GTK_TREE_MODEL (list_store)); + + priv->process_list_store = list_store; + priv->process_tree_view = tree_view; + /* set pointers to NULL when dialog goes away */ + g_object_add_weak_pointer (G_OBJECT (list_store), (gpointer *) &priv->process_list_store); + g_object_add_weak_pointer (G_OBJECT (tree_view), (gpointer *) &priv->process_tree_view); + + g_object_unref (list_store); + + gtk_widget_show_all (dialog); + g_object_ref (op); +} + +static void +gtk_mount_operation_show_processes (GMountOperation *op, + const char *message, + GArray *processes, + const char *choices[]) +{ + GtkMountOperationPrivate *priv; + + g_return_if_fail (GTK_IS_MOUNT_OPERATION (op)); + g_return_if_fail (message != NULL); + g_return_if_fail (processes != NULL); + g_return_if_fail (choices != NULL); + + priv = GTK_MOUNT_OPERATION (op)->priv; + + if (priv->process_list_store == NULL) + { + /* need to create the dialog */ + create_show_processes_dialog (op, message, choices); + } + + /* otherwise, we're showing the dialog, assume messages+choices hasn't changed */ + + update_process_list_store (GTK_MOUNT_OPERATION (op), + priv->process_list_store, + processes); +} + static void gtk_mount_operation_aborted (GMountOperation *op) { diff --git a/gtk/gtkmountoperationprivate.h b/gtk/gtkmountoperationprivate.h new file mode 100644 index 0000000000..89ce862690 --- /dev/null +++ b/gtk/gtkmountoperationprivate.h @@ -0,0 +1,53 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* GTK - The GIMP Toolkit + * Copyright (C) David Zeuthen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GTK+ Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. + */ + +#ifndef __GTK_MOUNT_OPERATION_PRIVATE_H__ +#define __GTK_MOUNT_OPERATION_PRIVATE_H__ + +#include +#include +#include + +struct _GtkMountOperationLookupContext; +typedef struct _GtkMountOperationLookupContext GtkMountOperationLookupContext; + +GtkMountOperationLookupContext *_gtk_mount_operation_lookup_context_get (GdkDisplay *display); + +gboolean _gtk_mount_operation_lookup_info (GtkMountOperationLookupContext *context, + GPid pid, + gint size_pixels, + gchar **out_name, + gchar **out_command_line, + GdkPixbuf **out_pixbuf); + +void _gtk_mount_operation_lookup_context_free (GtkMountOperationLookupContext *context); + +/* throw G_IO_ERROR_FAILED_HANDLED if a helper already reported the error to the user */ +gboolean _gtk_mount_operation_kill_process (GPid pid, + GError **error); + +#endif /* __GTK_MOUNT_OPERATION_PRIVATE_H__ */ diff --git a/gtk/gtknotebook.c b/gtk/gtknotebook.c index aa1a5ade06..2c6a507a4c 100644 --- a/gtk/gtknotebook.c +++ b/gtk/gtknotebook.c @@ -3094,8 +3094,6 @@ static gint gtk_notebook_focus_in (GtkWidget *widget, GdkEventFocus *event) { - GTK_NOTEBOOK (widget)->child_has_focus = FALSE; - gtk_notebook_redraw_tabs (GTK_NOTEBOOK (widget)); return FALSE; @@ -3978,6 +3976,8 @@ gtk_notebook_set_focus_child (GtkContainer *container, } } } + else + notebook->child_has_focus = FALSE; GTK_CONTAINER_CLASS (gtk_notebook_parent_class)->set_focus_child (container, child); } @@ -5799,9 +5799,14 @@ gtk_notebook_real_switch_page (GtkNotebook *notebook, GtkNotebookPage *page, guint page_num) { + gboolean child_has_focus; + if (notebook->cur_page == page || !GTK_WIDGET_VISIBLE (page->child)) return; + /* save the value here, changing visibility changes focus */ + child_has_focus = notebook->child_has_focus; + if (notebook->cur_page) gtk_widget_set_child_visible (notebook->cur_page->child, FALSE); @@ -5818,7 +5823,7 @@ gtk_notebook_real_switch_page (GtkNotebook *notebook, * element on the new page, if possible, or if not, to the * notebook itself. */ - if (notebook->child_has_focus) + if (child_has_focus) { if (notebook->cur_page->last_focus_child && gtk_widget_is_ancestor (notebook->cur_page->last_focus_child, notebook->cur_page->child)) diff --git a/gtk/gtkpagesetupunixdialog.c b/gtk/gtkpagesetupunixdialog.c index 8d9cbc787e..1e903391d9 100644 --- a/gtk/gtkpagesetupunixdialog.c +++ b/gtk/gtkpagesetupunixdialog.c @@ -23,10 +23,6 @@ #include #include -#ifdef HAVE__NL_MEASUREMENT_MEASUREMENT -#include -#endif - #include "gtkintl.h" #include "gtkprivate.h" @@ -54,14 +50,13 @@ #include "gtkhbbox.h" #include "gtkpagesetupunixdialog.h" +#include "gtkcustompaperunixdialog.h" #include "gtkprintbackend.h" #include "gtkprinter-private.h" #include "gtkpapersize.h" #include "gtkprintutils.h" #include "gtkalias.h" -#define CUSTOM_PAPER_FILENAME ".gtk-custom-papers" - struct GtkPageSetupUnixDialogPrivate { @@ -112,7 +107,6 @@ static void gtk_page_setup_unix_dialog_finalize (GObject *object static void populate_dialog (GtkPageSetupUnixDialog *dialog); static void fill_paper_sizes_from_printer (GtkPageSetupUnixDialog *dialog, GtkPrinter *printer); -static void show_custom_paper_dialog (GtkPageSetupUnixDialog *dialog); static void printer_added_cb (GtkPrintBackend *backend, GtkPrinter *printer, GtkPageSetupUnixDialog *dialog); @@ -140,140 +134,6 @@ static const gchar const common_paper_sizes[][16] = { "iso_a3", }; -static GtkUnit -get_default_user_units (void) -{ - /* Translate to the default units to use for presenting - * lengths to the user. Translate to default:inch if you - * want inches, otherwise translate to default:mm. - * Do *not* translate it to "predefinito:mm", if it - * it isn't default:mm or default:inch it will not work - */ - gchar *e = _("default:mm"); - -#ifdef HAVE__NL_MEASUREMENT_MEASUREMENT - gchar *imperial = NULL; - - imperial = nl_langinfo (_NL_MEASUREMENT_MEASUREMENT); - if (imperial && imperial[0] == 2 ) - return GTK_UNIT_INCH; /* imperial */ - if (imperial && imperial[0] == 1 ) - return GTK_UNIT_MM; /* metric */ -#endif - - if (strcmp (e, "default:inch")==0) - return GTK_UNIT_INCH; - else if (strcmp (e, "default:mm")) - g_warning ("Whoever translated default:mm did so wrongly.\n"); - return GTK_UNIT_MM; -} - -static char * -custom_paper_get_filename (void) -{ - gchar *filename; - - filename = g_build_filename (g_get_home_dir (), - CUSTOM_PAPER_FILENAME, NULL); - g_assert (filename != NULL); - return filename; -} - -GList * -_gtk_load_custom_papers (void) -{ - GKeyFile *keyfile; - gchar *filename; - gchar **groups; - gsize n_groups, i; - gboolean load_ok; - GList *result = NULL; - - filename = custom_paper_get_filename (); - - keyfile = g_key_file_new (); - load_ok = g_key_file_load_from_file (keyfile, filename, 0, NULL); - g_free (filename); - if (!load_ok) - { - g_key_file_free (keyfile); - return NULL; - } - - groups = g_key_file_get_groups (keyfile, &n_groups); - for (i = 0; i < n_groups; ++i) - { - GtkPageSetup *page_setup; - - page_setup = gtk_page_setup_new_from_key_file (keyfile, groups[i], NULL); - if (!page_setup) - continue; - - result = g_list_prepend (result, page_setup); - } - - g_strfreev (groups); - g_key_file_free (keyfile); - - return g_list_reverse (result); -} - -static void -load_custom_papers (GtkListStore *store) -{ - GtkTreeIter iter; - GList *papers, *p; - GtkPageSetup *page_setup; - - papers = _gtk_load_custom_papers (); - for (p = papers; p; p = p->next) - { - page_setup = p->data; - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, - 0, page_setup, - -1); - g_object_unref (page_setup); - } - - g_list_free (papers); -} - -static void -save_custom_papers (GtkListStore *store) -{ - GtkTreeModel *model = GTK_TREE_MODEL (store); - GtkTreeIter iter; - GKeyFile *keyfile; - gchar *filename, *data; - gsize len; - gint i = 0; - - keyfile = g_key_file_new (); - - if (gtk_tree_model_get_iter_first (model, &iter)) - { - do - { - GtkPageSetup *page_setup; - gchar group[32]; - - g_snprintf (group, sizeof (group), "Paper%u", i); - - gtk_tree_model_get (model, &iter, 0, &page_setup, -1); - - gtk_page_setup_to_key_file (page_setup, keyfile, group); - - ++i; - } while (gtk_tree_model_iter_next (model, &iter)); - } - - filename = custom_paper_get_filename (); - data = g_key_file_to_data (keyfile, &len, NULL); - g_file_set_contents (filename, data, len, NULL); - g_free (data); - g_free (filename); -} static void gtk_page_setup_unix_dialog_class_init (GtkPageSetupUnixDialogClass *class) @@ -286,7 +146,7 @@ gtk_page_setup_unix_dialog_class_init (GtkPageSetupUnixDialogClass *class) object_class->finalize = gtk_page_setup_unix_dialog_finalize; - g_type_class_add_private (class, sizeof (GtkPageSetupUnixDialogPrivate)); + g_type_class_add_private (class, sizeof (GtkPageSetupUnixDialogPrivate)); } static void @@ -294,27 +154,30 @@ gtk_page_setup_unix_dialog_init (GtkPageSetupUnixDialog *dialog) { GtkPageSetupUnixDialogPrivate *priv; GtkTreeIter iter; + gchar *tmp; priv = dialog->priv = GTK_PAGE_SETUP_UNIX_DIALOG_GET_PRIVATE (dialog); priv->print_backends = NULL; priv->printer_list = gtk_list_store_new (PRINTER_LIST_N_COLS, - G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_OBJECT); gtk_list_store_append (priv->printer_list, &iter); + tmp = g_strdup_printf ("%s\n%s", _("Any Printer"), _("For portable documents")); gtk_list_store_set (priv->printer_list, &iter, - PRINTER_LIST_COL_NAME, _("Any Printer\nFor portable documents"), + PRINTER_LIST_COL_NAME, tmp, PRINTER_LIST_COL_PRINTER, NULL, -1); - + g_free (tmp); + priv->page_setup_list = gtk_list_store_new (PAGE_SETUP_LIST_N_COLS, G_TYPE_OBJECT, G_TYPE_BOOLEAN); priv->custom_paper_list = gtk_list_store_new (1, G_TYPE_OBJECT); - load_custom_papers (priv->custom_paper_list); + _gtk_print_load_custom_papers (priv->custom_paper_list); populate_dialog (dialog); @@ -400,7 +263,7 @@ printer_added_cb (GtkPrintBackend *backend, GtkPageSetupUnixDialogPrivate *priv = dialog->priv; GtkTreeIter iter; gchar *str; - const gchar *location;; + const gchar *location; if (gtk_printer_is_virtual (printer)) return; @@ -411,18 +274,17 @@ printer_added_cb (GtkPrintBackend *backend, str = g_strdup_printf ("%s\n%s", gtk_printer_get_name (printer), location); - + gtk_list_store_append (priv->printer_list, &iter); gtk_list_store_set (priv->printer_list, &iter, PRINTER_LIST_COL_NAME, str, PRINTER_LIST_COL_PRINTER, printer, -1); - g_object_set_data_full (G_OBJECT (printer), - "gtk-print-tree-iter", + g_object_set_data_full (G_OBJECT (printer), + "gtk-print-tree-iter", gtk_tree_iter_copy (&iter), (GDestroyNotify) gtk_tree_iter_free); - g_free (str); if (priv->waiting_for_printer != NULL && @@ -456,7 +318,7 @@ printer_status_cb (GtkPrintBackend *backend, GtkPageSetupUnixDialogPrivate *priv = dialog->priv; GtkTreeIter *iter; gchar *str; - const gchar *location;; + const gchar *location; iter = g_object_get_data (G_OBJECT (printer), "gtk-print-tree-iter"); @@ -847,6 +709,23 @@ double_to_string (gdouble d, return val; } + +static void +custom_paper_dialog_response_cb (GtkDialog *custom_paper_dialog, + gint response_id, + gpointer user_data) +{ + GtkPageSetupUnixDialog *page_setup_dialog = GTK_PAGE_SETUP_UNIX_DIALOG (user_data); + GtkPageSetupUnixDialogPrivate *priv = page_setup_dialog->priv; + + _gtk_print_load_custom_papers (priv->custom_paper_list); + + /* Update printer page list */ + printer_changed_callback (GTK_COMBO_BOX (priv->printer_combo), page_setup_dialog); + + gtk_widget_destroy (GTK_WIDGET (custom_paper_dialog)); +} + static void paper_size_changed (GtkComboBox *combo_box, GtkPageSetupUnixDialog *dialog) @@ -869,6 +748,8 @@ paper_size_changed (GtkComboBox *combo_box, if (page_setup == NULL) { + GtkWidget *custom_paper_dialog; + /* Change from "manage" menu item to last value */ if (priv->last_setup) last_page_setup = g_object_ref (priv->last_setup); @@ -878,7 +759,9 @@ paper_size_changed (GtkComboBox *combo_box, g_object_unref (last_page_setup); /* And show the custom paper dialog */ - show_custom_paper_dialog (dialog); + custom_paper_dialog = _gtk_custom_paper_unix_dialog_new (GTK_WINDOW (dialog), NULL); + g_signal_connect (custom_paper_dialog, "response", G_CALLBACK (custom_paper_dialog_response_cb), dialog); + gtk_window_present (GTK_WINDOW (custom_paper_dialog)); return; } @@ -888,7 +771,7 @@ paper_size_changed (GtkComboBox *combo_box, priv->last_setup = g_object_ref (page_setup); - unit = get_default_user_units (); + unit = _gtk_print_get_default_user_units (); if (unit == GTK_UNIT_MM) unit_str = _("mm"); @@ -1311,755 +1194,5 @@ gtk_page_setup_unix_dialog_get_print_settings (GtkPageSetupUnixDialog *dialog) return priv->print_settings; } -static GtkWidget * -wrap_in_frame (const gchar *label, - GtkWidget *child) -{ - GtkWidget *frame, *alignment, *label_widget; - gchar *bold_text; - - label_widget = gtk_label_new (NULL); - gtk_misc_set_alignment (GTK_MISC (label_widget), 0.0, 0.5); - gtk_widget_show (label_widget); - - bold_text = g_markup_printf_escaped ("%s", label); - gtk_label_set_markup (GTK_LABEL (label_widget), bold_text); - g_free (bold_text); - - frame = gtk_vbox_new (FALSE, 6); - gtk_box_pack_start (GTK_BOX (frame), label_widget, FALSE, FALSE, 0); - - alignment = gtk_alignment_new (0.0, 0.0, 1.0, 1.0); - gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), - 0, 0, 12, 0); - gtk_box_pack_start (GTK_BOX (frame), alignment, FALSE, FALSE, 0); - - gtk_container_add (GTK_CONTAINER (alignment), child); - - gtk_widget_show (frame); - gtk_widget_show (alignment); - - return frame; -} - -typedef struct -{ - GtkUnit display_unit; - GtkWidget *spin_button; -} UnitWidget; - -typedef struct -{ - GtkPageSetupUnixDialog *dialog; - GtkWidget *treeview; - GtkTreeViewColumn *text_column; - GtkWidget *values_box; - GtkWidget *printer_combo; - GtkWidget *width_widget; - GtkWidget *height_widget; - GtkWidget *top_widget; - GtkWidget *bottom_widget; - GtkWidget *left_widget; - GtkWidget *right_widget; - gulong printer_inserted_tag; - gulong printer_removed_tag; - guint request_details_tag; - GtkPrinter *request_details_printer; - guint non_user_change : 1; -} CustomPaperDialog; - -static void unit_widget_changed (CustomPaperDialog *data); - -static GtkWidget * -new_unit_widget (CustomPaperDialog *dialog, - GtkUnit unit, - GtkWidget *mnemonic_label) -{ - GtkWidget *hbox, *button, *label; - UnitWidget *data; - - data = g_new0 (UnitWidget, 1); - data->display_unit = unit; - - hbox = gtk_hbox_new (FALSE, 6); - - button = gtk_spin_button_new_with_range (0.0, 9999.0, 1); - if (unit == GTK_UNIT_INCH) - gtk_spin_button_set_digits (GTK_SPIN_BUTTON (button), 2); - else - gtk_spin_button_set_digits (GTK_SPIN_BUTTON (button), 1); - - gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0); - gtk_widget_show (button); - - data->spin_button = button; - - g_signal_connect_swapped (button, "value-changed", - G_CALLBACK (unit_widget_changed), dialog); - - if (unit == GTK_UNIT_INCH) - label = gtk_label_new (_("inch")); - else - label = gtk_label_new (_("mm")); - - gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); - gtk_widget_show (label); - gtk_label_set_mnemonic_widget (GTK_LABEL (mnemonic_label), button); - - g_object_set_data_full (G_OBJECT (hbox), "unit-data", data, g_free); - - return hbox; -} - -static double -unit_widget_get (GtkWidget *unit_widget) -{ - UnitWidget *data = g_object_get_data (G_OBJECT (unit_widget), "unit-data"); - return _gtk_print_convert_to_mm (gtk_spin_button_get_value (GTK_SPIN_BUTTON (data->spin_button)), - data->display_unit); -} - -static void -unit_widget_set (GtkWidget *unit_widget, - gdouble value) -{ - UnitWidget *data; - - data = g_object_get_data (G_OBJECT (unit_widget), "unit-data"); - gtk_spin_button_set_value (GTK_SPIN_BUTTON (data->spin_button), - _gtk_print_convert_from_mm (value, data->display_unit)); -} - -static void -custom_paper_printer_data_func (GtkCellLayout *cell_layout, - GtkCellRenderer *cell, - GtkTreeModel *tree_model, - GtkTreeIter *iter, - gpointer data) -{ - GtkPrinter *printer; - - gtk_tree_model_get (tree_model, iter, - PRINTER_LIST_COL_PRINTER, &printer, -1); - - if (printer) - g_object_set (cell, "text", gtk_printer_get_name (printer), NULL); - else - g_object_set (cell, "text", _("Margins from Printer..."), NULL); - - if (printer) - g_object_unref (printer); -} - -static void -update_combo_sensitivity_from_printers (CustomPaperDialog *data) -{ - GtkTreeIter iter; - gboolean sensitive; - GtkTreeSelection *selection; - GtkTreeModel *model; - - sensitive = FALSE; - model = GTK_TREE_MODEL (data->dialog->priv->printer_list); - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (data->treeview)); - if (gtk_tree_model_get_iter_first (model, &iter) && - gtk_tree_model_iter_next (model, &iter) && - gtk_tree_selection_get_selected (selection, NULL, &iter)) - sensitive = TRUE; - - gtk_widget_set_sensitive (data->printer_combo, sensitive); -} - -static void -update_custom_widgets_from_list (CustomPaperDialog *data) -{ - GtkTreeSelection *selection; - GtkTreeModel *model; - GtkTreeIter iter; - GtkPageSetup *page_setup; - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (data->treeview)); - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (data->treeview)); - - data->non_user_change = TRUE; - if (gtk_tree_selection_get_selected (selection, NULL, &iter)) - { - gtk_tree_model_get (model, &iter, 0, &page_setup, -1); - - unit_widget_set (data->width_widget, - gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_MM)); - unit_widget_set (data->height_widget, - gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_MM)); - unit_widget_set (data->top_widget, - gtk_page_setup_get_top_margin (page_setup, GTK_UNIT_MM)); - unit_widget_set (data->bottom_widget, - gtk_page_setup_get_bottom_margin (page_setup, GTK_UNIT_MM)); - unit_widget_set (data->left_widget, - gtk_page_setup_get_left_margin (page_setup, GTK_UNIT_MM)); - unit_widget_set (data->right_widget, - gtk_page_setup_get_right_margin (page_setup, GTK_UNIT_MM)); - - gtk_widget_set_sensitive (data->values_box, TRUE); - } - else - { - gtk_widget_set_sensitive (data->values_box, FALSE); - } - - update_combo_sensitivity_from_printers (data); - data->non_user_change = FALSE; -} - -static void -selected_custom_paper_changed (GtkTreeSelection *selection, - CustomPaperDialog *data) -{ - update_custom_widgets_from_list (data); -} - -static void -unit_widget_changed (CustomPaperDialog *data) -{ - gdouble w, h, top, bottom, left, right; - GtkTreeSelection *selection; - GtkTreeIter iter; - GtkPageSetup *page_setup; - GtkPaperSize *paper_size; - - if (data->non_user_change) - return; - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (data->treeview)); - - if (gtk_tree_selection_get_selected (selection, NULL, &iter)) - { - gtk_tree_model_get (GTK_TREE_MODEL (data->dialog->priv->custom_paper_list), &iter, 0, &page_setup, -1); - - w = unit_widget_get (data->width_widget); - h = unit_widget_get (data->height_widget); - - paper_size = gtk_page_setup_get_paper_size (page_setup); - gtk_paper_size_set_size (paper_size, w, h, GTK_UNIT_MM); - - top = unit_widget_get (data->top_widget); - bottom = unit_widget_get (data->bottom_widget); - left = unit_widget_get (data->left_widget); - right = unit_widget_get (data->right_widget); - - gtk_page_setup_set_top_margin (page_setup, top, GTK_UNIT_MM); - gtk_page_setup_set_bottom_margin (page_setup, bottom, GTK_UNIT_MM); - gtk_page_setup_set_left_margin (page_setup, left, GTK_UNIT_MM); - gtk_page_setup_set_right_margin (page_setup, right, GTK_UNIT_MM); - - g_object_unref (page_setup); - } -} - -static gboolean -custom_paper_name_used (CustomPaperDialog *data, - const gchar *name) -{ - GtkTreeModel *model; - GtkTreeIter iter; - GtkPageSetup *page_setup; - GtkPaperSize *paper_size; - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (data->treeview)); - - if (gtk_tree_model_get_iter_first (model, &iter)) - { - do - { - gtk_tree_model_get (model, &iter, 0, &page_setup, -1); - paper_size = gtk_page_setup_get_paper_size (page_setup); - if (strcmp (name, - gtk_paper_size_get_name (paper_size)) == 0) - { - g_object_unref (page_setup); - return TRUE; - } - g_object_unref (page_setup); - } while (gtk_tree_model_iter_next (model, &iter)); - } - - return FALSE; -} - -static void -add_custom_paper (CustomPaperDialog *data) -{ - GtkListStore *store; - GtkPageSetup *page_setup; - GtkPaperSize *paper_size; - GtkTreeSelection *selection; - GtkTreePath *path; - GtkTreeIter iter; - gchar *name; - gint i; - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (data->treeview)); - store = data->dialog->priv->custom_paper_list; - - i = 1; - name = NULL; - do - { - g_free (name); - name = g_strdup_printf (_("Custom Size %d"), i); - i++; - } while (custom_paper_name_used (data, name)); - - page_setup = gtk_page_setup_new (); - paper_size = gtk_paper_size_new_custom (name, name, - gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_MM), - gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_MM), - GTK_UNIT_MM); - gtk_page_setup_set_paper_size (page_setup, paper_size); - gtk_paper_size_free (paper_size); - - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, 0, page_setup, -1); - g_object_unref (page_setup); - - gtk_tree_selection_select_iter (selection, &iter); - path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter); - gtk_widget_grab_focus (data->treeview); - gtk_tree_view_set_cursor (GTK_TREE_VIEW (data->treeview), path, - data->text_column, TRUE); - gtk_tree_path_free (path); - g_free (name); -} - -static void -remove_custom_paper (CustomPaperDialog *data) -{ - GtkTreeSelection *selection; - GtkTreeIter iter; - GtkListStore *store; - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (data->treeview)); - store = data->dialog->priv->custom_paper_list; - - if (gtk_tree_selection_get_selected (selection, NULL, &iter)) - { - GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter); - gtk_list_store_remove (store, &iter); - - if (gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path)) - gtk_tree_selection_select_iter (selection, &iter); - else if (gtk_tree_path_prev (path) && gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path)) - gtk_tree_selection_select_iter (selection, &iter); - - gtk_tree_path_free (path); - } -} - -static void -set_margins_from_printer (CustomPaperDialog *data, - GtkPrinter *printer) -{ - gdouble top, bottom, left, right; - - top = bottom = left = right = 0; - _gtk_printer_get_hard_margins (printer, &top, &bottom, &left, &right); - - data->non_user_change = TRUE; - unit_widget_set (data->top_widget, _gtk_print_convert_to_mm (top, GTK_UNIT_POINTS)); - unit_widget_set (data->bottom_widget, _gtk_print_convert_to_mm (bottom, GTK_UNIT_POINTS)); - unit_widget_set (data->left_widget, _gtk_print_convert_to_mm (left, GTK_UNIT_POINTS)); - unit_widget_set (data->right_widget, _gtk_print_convert_to_mm (right, GTK_UNIT_POINTS)); - data->non_user_change = FALSE; - - /* Only send one change */ - unit_widget_changed (data); -} - -static void -get_margins_finished_callback (GtkPrinter *printer, - gboolean success, - CustomPaperDialog *data) -{ - g_signal_handler_disconnect (data->request_details_printer, - data->request_details_tag); - g_object_unref (data->request_details_printer); - data->request_details_tag = 0; - data->request_details_printer = NULL; - - if (success) - set_margins_from_printer (data, printer); - - gtk_combo_box_set_active (GTK_COMBO_BOX (data->printer_combo), 0); -} - -static void -margins_from_printer_changed (CustomPaperDialog *data) -{ - GtkTreeIter iter; - GtkComboBox *combo; - GtkPrinter *printer; - - combo = GTK_COMBO_BOX (data->printer_combo); - - if (data->request_details_tag) - { - g_signal_handler_disconnect (data->request_details_printer, - data->request_details_tag); - g_object_unref (data->request_details_printer); - data->request_details_printer = NULL; - data->request_details_tag = 0; - } - - if (gtk_combo_box_get_active_iter (combo, &iter)) - { - gtk_tree_model_get (gtk_combo_box_get_model (combo), &iter, - PRINTER_LIST_COL_PRINTER, &printer, -1); - - if (printer) - { - if (gtk_printer_has_details (printer)) - { - set_margins_from_printer (data, printer); - gtk_combo_box_set_active (combo, 0); - } - else - { - data->request_details_printer = g_object_ref (printer); - data->request_details_tag = - g_signal_connect (printer, "details-acquired", - G_CALLBACK (get_margins_finished_callback), data); - gtk_printer_request_details (printer); - } - - g_object_unref (printer); - } - } -} - - -static void -custom_paper_dialog_free (gpointer p) -{ - CustomPaperDialog *data = p; - GtkPageSetupUnixDialogPrivate *priv = data->dialog->priv; - - g_signal_handler_disconnect (priv->printer_list, data->printer_inserted_tag); - g_signal_handler_disconnect (priv->printer_list, data->printer_removed_tag); - - if (data->request_details_tag) - { - g_signal_handler_disconnect (data->request_details_printer, - data->request_details_tag); - g_object_unref (data->request_details_printer); - data->request_details_printer = NULL; - data->request_details_tag = 0; - } - - g_free (data); -} - -static void -custom_size_name_edited (GtkCellRenderer *cell, - gchar *path_string, - gchar *new_text, - CustomPaperDialog *data) -{ - GtkTreePath *path; - GtkTreeIter iter; - GtkListStore *store; - GtkPageSetup *page_setup; - GtkPaperSize *paper_size; - - store = data->dialog->priv->custom_paper_list; - path = gtk_tree_path_new_from_string (path_string); - gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path); - gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, 0, &page_setup, -1); - gtk_tree_path_free (path); - - paper_size = gtk_paper_size_new_custom (new_text, new_text, - gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_MM), - gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_MM), - GTK_UNIT_MM); - gtk_page_setup_set_paper_size (page_setup, paper_size); - gtk_paper_size_free (paper_size); - - g_object_unref (page_setup); -} - -static void -custom_name_func (GtkTreeViewColumn *tree_column, - GtkCellRenderer *cell, - GtkTreeModel *tree_model, - GtkTreeIter *iter, - gpointer data) -{ - GtkPageSetup *page_setup; - GtkPaperSize *paper_size; - - gtk_tree_model_get (tree_model, iter, 0, &page_setup, -1); - if (page_setup) - { - paper_size = gtk_page_setup_get_paper_size (page_setup); - g_object_set (cell, "text", gtk_paper_size_get_display_name (paper_size), NULL); - g_object_unref (page_setup); - } -} - -static void -custom_paper_dialog_response_cb (GtkWidget *custom_dialog, - gint response, - CustomPaperDialog *data) -{ - GtkPageSetupUnixDialog *dialog = data->dialog; - GtkPageSetupUnixDialogPrivate *priv = dialog->priv; - - save_custom_papers (priv->custom_paper_list); - - /* Update printer page list */ - printer_changed_callback (GTK_COMBO_BOX (priv->printer_combo), dialog); - - gtk_widget_destroy (custom_dialog); -} - -static void -show_custom_paper_dialog (GtkPageSetupUnixDialog *ps_dialog) -{ - GtkPageSetupUnixDialogPrivate *priv = ps_dialog->priv; - GtkWidget *custom_dialog, *image, *table, *label, *widget, *frame, *combo; - GtkWidget *hbox, *vbox, *treeview, *scrolled, *button_box, *button; - GtkDialog *dialog; - GtkCellRenderer *cell; - GtkTreeViewColumn *column; - GtkTreeIter iter; - GtkTreeSelection *selection; - CustomPaperDialog *data; - GtkUnit user_units; - - custom_dialog = gtk_dialog_new_with_buttons (_("Manage Custom Sizes"), - GTK_WINDOW (ps_dialog), - GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR, - GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, - NULL); - - dialog = GTK_DIALOG (custom_dialog); - - data = g_new0 (CustomPaperDialog, 1); - data->dialog = ps_dialog; - g_object_set_data_full (G_OBJECT (custom_dialog), "custom-dialog", data, - custom_paper_dialog_free); - g_signal_connect (dialog, "response", - G_CALLBACK (custom_paper_dialog_response_cb), data); - - gtk_dialog_set_has_separator (dialog, FALSE); - gtk_container_set_border_width (GTK_CONTAINER (dialog), 5); - gtk_box_set_spacing (GTK_BOX (dialog->vbox), 2); /* 2 * 5 + 2 = 12 */ - gtk_container_set_border_width (GTK_CONTAINER (dialog->action_area), 5); - gtk_box_set_spacing (GTK_BOX (dialog->action_area), 6); - - hbox = gtk_hbox_new (FALSE, 18); - gtk_container_set_border_width (GTK_CONTAINER (hbox), 5); - gtk_box_pack_start (GTK_BOX (dialog->vbox), hbox, TRUE, TRUE, 0); - gtk_widget_show (hbox); - - vbox = gtk_vbox_new (FALSE, 6); - gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0); - gtk_widget_show (vbox); - - scrolled = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled), - GTK_SHADOW_IN); - gtk_box_pack_start (GTK_BOX (vbox), scrolled, TRUE, TRUE, 0); - gtk_widget_show (scrolled); - - treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (priv->custom_paper_list)); - data->treeview = treeview; - gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE); - gtk_widget_set_size_request (treeview, 140, -1); - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); - gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE); - g_signal_connect (selection, "changed", G_CALLBACK (selected_custom_paper_changed), data); - - cell = gtk_cell_renderer_text_new (); - g_object_set (cell, "editable", TRUE, NULL); - g_signal_connect (cell, "edited", - G_CALLBACK (custom_size_name_edited), data); - data->text_column = column = - gtk_tree_view_column_new_with_attributes ("paper", cell, - NULL); - gtk_tree_view_column_set_cell_data_func (column, cell, custom_name_func, NULL, NULL); - - gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); - - gtk_container_add (GTK_CONTAINER (scrolled), treeview); - gtk_widget_show (treeview); - - button_box = gtk_hbox_new (FALSE, 6); - gtk_box_pack_start (GTK_BOX (vbox), button_box, FALSE, FALSE, 0); - gtk_widget_show (button_box); - - button = gtk_button_new (); - image = gtk_image_new_from_stock (GTK_STOCK_ADD, GTK_ICON_SIZE_BUTTON); - gtk_widget_show (image); - gtk_container_add (GTK_CONTAINER (button), image); - gtk_box_pack_start (GTK_BOX (button_box), button, FALSE, FALSE, 0); - gtk_widget_show (button); - - g_signal_connect_swapped (button, "clicked", G_CALLBACK (add_custom_paper), data); - - button = gtk_button_new (); - image = gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_BUTTON); - gtk_widget_show (image); - gtk_container_add (GTK_CONTAINER (button), image); - gtk_box_pack_start (GTK_BOX (button_box), button, FALSE, FALSE, 0); - gtk_widget_show (button); - - g_signal_connect_swapped (button, "clicked", G_CALLBACK (remove_custom_paper), data); - - user_units = get_default_user_units (); - - vbox = gtk_vbox_new (FALSE, 18); - data->values_box = vbox; - gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0); - gtk_widget_show (vbox); - - table = gtk_table_new (2, 2, FALSE); - - gtk_table_set_row_spacings (GTK_TABLE (table), 6); - gtk_table_set_col_spacings (GTK_TABLE (table), 12); - - label = gtk_label_new_with_mnemonic (_("_Width:")); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_widget_show (label); - gtk_table_attach (GTK_TABLE (table), label, - 0, 1, 0, 1, GTK_FILL, 0, 0, 0); - - widget = new_unit_widget (data, user_units, label); - data->width_widget = widget; - gtk_table_attach (GTK_TABLE (table), widget, - 1, 2, 0, 1, GTK_FILL, 0, 0, 0); - gtk_widget_show (widget); - - label = gtk_label_new_with_mnemonic (_("_Height:")); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_widget_show (label); - gtk_table_attach (GTK_TABLE (table), label, - 0, 1, 1, 2, GTK_FILL, 0, 0, 0); - - widget = new_unit_widget (data, user_units, label); - data->height_widget = widget; - gtk_table_attach (GTK_TABLE (table), widget, - 1, 2, 1, 2, GTK_FILL, 0, 0, 0); - gtk_widget_show (widget); - - frame = wrap_in_frame (_("Paper Size"), table); - gtk_widget_show (table); - gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); - gtk_widget_show (frame); - - - table = gtk_table_new (5, 2, FALSE); - gtk_table_set_row_spacings (GTK_TABLE (table), 6); - gtk_table_set_col_spacings (GTK_TABLE (table), 12); - - label = gtk_label_new_with_mnemonic (_("_Top:")); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_table_attach (GTK_TABLE (table), label, - 0, 1, 0, 1, GTK_FILL, 0, 0, 0); - gtk_widget_show (label); - - widget = new_unit_widget (data, user_units, label); - data->top_widget = widget; - gtk_table_attach (GTK_TABLE (table), widget, - 1, 2, 0, 1, GTK_FILL, 0, 0, 0); - gtk_widget_show (widget); - - label = gtk_label_new_with_mnemonic (_("_Bottom:")); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_table_attach (GTK_TABLE (table), label, - 0, 1 , 1, 2, GTK_FILL, 0, 0, 0); - gtk_widget_show (label); - - widget = new_unit_widget (data, user_units, label); - data->bottom_widget = widget; - gtk_table_attach (GTK_TABLE (table), widget, - 1, 2, 1, 2, GTK_FILL, 0, 0, 0); - gtk_widget_show (widget); - - label = gtk_label_new_with_mnemonic (_("_Left:")); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_table_attach (GTK_TABLE (table), label, - 0, 1, 2, 3, GTK_FILL, 0, 0, 0); - gtk_widget_show (label); - - widget = new_unit_widget (data, user_units, label); - data->left_widget = widget; - gtk_table_attach (GTK_TABLE (table), widget, - 1, 2, 2, 3, GTK_FILL, 0, 0, 0); - gtk_widget_show (widget); - - label = gtk_label_new_with_mnemonic (_("_Right:")); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_table_attach (GTK_TABLE (table), label, - 0, 1, 3, 4, GTK_FILL, 0, 0, 0); - gtk_widget_show (label); - - widget = new_unit_widget (data, user_units, label); - data->right_widget = widget; - gtk_table_attach (GTK_TABLE (table), widget, - 1, 2, 3, 4, GTK_FILL, 0, 0, 0); - gtk_widget_show (widget); - - hbox = gtk_hbox_new (FALSE, 0); - gtk_table_attach (GTK_TABLE (table), hbox, - 0, 2, 4, 5, GTK_FILL | GTK_EXPAND, 0, 0, 0); - gtk_widget_show (hbox); - - combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (priv->printer_list)); - data->printer_combo = combo; - - data->printer_inserted_tag = - g_signal_connect_swapped (priv->printer_list, "row-inserted", - G_CALLBACK (update_combo_sensitivity_from_printers), data); - data->printer_removed_tag = - g_signal_connect_swapped (priv->printer_list, "row-deleted", - G_CALLBACK (update_combo_sensitivity_from_printers), data); - update_combo_sensitivity_from_printers (data); - - cell = gtk_cell_renderer_text_new (); - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), cell, TRUE); - gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combo), cell, - custom_paper_printer_data_func, - NULL, NULL); - - gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0); - gtk_box_pack_start (GTK_BOX (hbox), combo, FALSE, FALSE, 0); - gtk_widget_show (combo); - - g_signal_connect_swapped (combo, "changed", - G_CALLBACK (margins_from_printer_changed), data); - - frame = wrap_in_frame (_("Paper Margins"), table); - gtk_widget_show (table); - gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); - gtk_widget_show (frame); - - update_custom_widgets_from_list (data); - - /* If no custom sizes, add one */ - if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->custom_paper_list), - &iter)) - { - /* Need to realize treeview so we can start the rename */ - gtk_widget_realize (treeview); - add_custom_paper (data); - } - - gtk_window_present (GTK_WINDOW (dialog)); -} - - #define __GTK_PAGE_SETUP_UNIX_DIALOG_C__ #include "gtkaliasdef.c" diff --git a/gtk/gtkprintbackend.c b/gtk/gtkprintbackend.c index 567273bdd7..3c64823ebe 100644 --- a/gtk/gtkprintbackend.c +++ b/gtk/gtkprintbackend.c @@ -50,9 +50,8 @@ struct _GtkPrintBackendPrivate guint printer_list_requested : 1; guint printer_list_done : 1; GtkPrintBackendStatus status; - char *hostname; - char *username; - char *password; + char **auth_info_required; + char **auth_info; }; enum { @@ -359,8 +358,10 @@ static GList * fallback_printer_list_papers (GtkPrinter static GtkPageSetup * fallback_printer_get_default_page_size (GtkPrinter *printer); static GtkPrintCapabilities fallback_printer_get_capabilities (GtkPrinter *printer); static void request_password (GtkPrintBackend *backend, - const gchar *hostname, - const gchar *username, + gpointer auth_info_required, + gpointer auth_info_default, + gpointer auth_info_display, + gpointer auth_info_visible, const gchar *prompt); static void @@ -441,8 +442,8 @@ gtk_print_backend_class_init (GtkPrintBackendClass *class) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GtkPrintBackendClass, request_password), NULL, NULL, - _gtk_marshal_VOID__STRING_STRING_STRING, - G_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); + _gtk_marshal_VOID__POINTER_POINTER_POINTER_POINTER_STRING, + G_TYPE_NONE, 5, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_STRING); } static void @@ -455,9 +456,8 @@ gtk_print_backend_init (GtkPrintBackend *backend) priv->printers = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) g_object_unref); - priv->hostname = NULL; - priv->username = NULL; - priv->password = NULL; + priv->auth_info_required = NULL; + priv->auth_info = NULL; } static void @@ -662,40 +662,29 @@ gtk_print_backend_print_stream (GtkPrintBackend *backend, } void -gtk_print_backend_set_password (GtkPrintBackend *backend, - const gchar *hostname, - const gchar *username, - const gchar *password) +gtk_print_backend_set_password (GtkPrintBackend *backend, + gchar **auth_info_required, + gchar **auth_info) { g_return_if_fail (GTK_IS_PRINT_BACKEND (backend)); if (GTK_PRINT_BACKEND_GET_CLASS (backend)->set_password) - GTK_PRINT_BACKEND_GET_CLASS (backend)->set_password (backend, hostname, username, password); + GTK_PRINT_BACKEND_GET_CLASS (backend)->set_password (backend, auth_info_required, auth_info); } static void -store_password (GtkEntry *entry, - GtkPrintBackend *backend) +store_entry (GtkEntry *entry, + gpointer user_data) { - GtkPrintBackendPrivate *priv = backend->priv; + gchar **data = (gchar **) user_data; - if (priv->password != NULL) + if (*data != NULL) { - memset (priv->password, 0, strlen (priv->password)); - g_free (priv->password); + memset (*data, 0, strlen (*data)); + g_free (*data); } - priv->password = g_strdup (gtk_entry_get_text (entry)); -} - -static void -store_username (GtkEntry *entry, - GtkPrintBackend *backend) -{ - GtkPrintBackendPrivate *priv = backend->priv; - - g_free (priv->username); - priv->username = g_strdup (gtk_entry_get_text (entry)); + *data = g_strdup (gtk_entry_get_text (entry)); } static void @@ -704,21 +693,24 @@ password_dialog_response (GtkWidget *dialog, GtkPrintBackend *backend) { GtkPrintBackendPrivate *priv = backend->priv; + gint i; if (response_id == GTK_RESPONSE_OK) - gtk_print_backend_set_password (backend, priv->hostname, priv->username, priv->password); + gtk_print_backend_set_password (backend, priv->auth_info_required, priv->auth_info); else - gtk_print_backend_set_password (backend, priv->hostname, priv->username, NULL); + gtk_print_backend_set_password (backend, priv->auth_info_required, NULL); - if (priv->password != NULL) - { - memset (priv->password, 0, strlen (priv->password)); - g_free (priv->password); - priv->password = NULL; - } + for (i = 0; i < g_strv_length (priv->auth_info_required); i++) + if (priv->auth_info[i] != NULL) + { + memset (priv->auth_info[i], 0, strlen (priv->auth_info[i])); + g_free (priv->auth_info[i]); + priv->auth_info[i] = NULL; + } + g_free (priv->auth_info); + priv->auth_info = NULL; - g_free (priv->username); - priv->username = NULL; + g_strfreev (priv->auth_info_required); gtk_widget_destroy (dialog); @@ -726,16 +718,27 @@ password_dialog_response (GtkWidget *dialog, } static void -request_password (GtkPrintBackend *backend, - const gchar *hostname, - const gchar *username, - const gchar *prompt) +request_password (GtkPrintBackend *backend, + gpointer auth_info_required, + gpointer auth_info_default, + gpointer auth_info_display, + gpointer auth_info_visible, + const gchar *prompt) { GtkPrintBackendPrivate *priv = backend->priv; - GtkWidget *dialog, *username_box, *password_box, *main_box, *label, *icon, *vbox, - *password_prompt, *username_prompt, - *password_entry, *username_entry; + GtkWidget *dialog, *box, *main_box, *label, *icon, *vbox, *entry; + GtkWidget *focus = NULL; gchar *markup; + gint length; + gint i; + gchar **ai_required = (gchar **) auth_info_required; + gchar **ai_default = (gchar **) auth_info_default; + gchar **ai_display = (gchar **) auth_info_display; + gboolean *ai_visible = (gboolean *) auth_info_visible; + + priv->auth_info_required = g_strdupv (ai_required); + length = g_strv_length (ai_required); + priv->auth_info = g_new0 (gchar *, length); dialog = gtk_dialog_new_with_buttons ( _("Authentication"), NULL, GTK_DIALOG_MODAL, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, @@ -766,27 +769,6 @@ request_password (GtkPrintBackend *backend, g_free (markup); - /* Right - 2. */ - username_box = gtk_hbox_new (TRUE, 0); - - username_prompt = gtk_label_new (_("Username:")); - gtk_misc_set_alignment (GTK_MISC (username_prompt), 0.0, 0.5); - - username_entry = gtk_entry_new (); - gtk_entry_set_text (GTK_ENTRY (username_entry), username); - - - /* Right - 3. */ - password_box = gtk_hbox_new (TRUE, 0); - - password_prompt = gtk_label_new (_("Password:")); - gtk_misc_set_alignment (GTK_MISC (password_prompt), 0.0, 0.5); - - password_entry = gtk_entry_new (); - gtk_entry_set_visibility (GTK_ENTRY (password_entry), FALSE); - gtk_entry_set_activates_default (GTK_ENTRY (password_entry), TRUE); - - /* Packing */ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), main_box, TRUE, FALSE, 0); @@ -794,26 +776,42 @@ request_password (GtkPrintBackend *backend, gtk_box_pack_start (GTK_BOX (main_box), vbox, FALSE, FALSE, 6); gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 6); - gtk_box_pack_start (GTK_BOX (vbox), username_box, FALSE, TRUE, 6); - gtk_box_pack_start (GTK_BOX (vbox), password_box, FALSE, TRUE, 6); + + /* Right - 2. */ + for (i = 0; i < length; i++) + { + priv->auth_info[i] = g_strdup (ai_default[i]); + if (ai_display[i] != NULL) + { + box = gtk_hbox_new (TRUE, 0); - gtk_box_pack_start (GTK_BOX (username_box), username_prompt, TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (username_box), username_entry, TRUE, TRUE, 0); + label = gtk_label_new (ai_display[i]); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_box_pack_start (GTK_BOX (password_box), password_prompt, TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (password_box), password_entry, TRUE, TRUE, 0); + entry = gtk_entry_new (); + focus = entry; + if (ai_default[i] != NULL) + gtk_entry_set_text (GTK_ENTRY (entry), ai_default[i]); - gtk_widget_grab_focus (password_entry); + gtk_entry_set_visibility (GTK_ENTRY (entry), ai_visible[i]); + gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE); - priv->hostname = g_strdup (hostname); - priv->username = g_strdup (username); + gtk_box_pack_start (GTK_BOX (vbox), box, FALSE, TRUE, 6); - g_signal_connect (password_entry, "changed", - G_CALLBACK (store_password), backend); + gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (box), entry, TRUE, TRUE, 0); - g_signal_connect (username_entry, "changed", - G_CALLBACK (store_username), backend); + g_signal_connect (entry, "changed", + G_CALLBACK (store_entry), &(priv->auth_info[i])); + } + } + + if (focus != NULL) + { + gtk_widget_grab_focus (focus); + focus = NULL; + } g_object_ref (backend); g_signal_connect (G_OBJECT (dialog), "response", diff --git a/gtk/gtkprintbackend.h b/gtk/gtkprintbackend.h index 7d75f8e417..c4b43b10d2 100644 --- a/gtk/gtkprintbackend.h +++ b/gtk/gtkprintbackend.h @@ -121,15 +121,16 @@ struct _GtkPrintBackendClass void (*printer_status_changed) (GtkPrintBackend *backend, GtkPrinter *printer); void (*request_password) (GtkPrintBackend *backend, - const gchar *hostname, - const gchar *username, + gpointer auth_info_required, + gpointer auth_info_default, + gpointer auth_info_display, + gpointer auth_info_visible, const gchar *prompt); /* not a signal */ void (*set_password) (GtkPrintBackend *backend, - const gchar *hostname, - const gchar *username, - const gchar *password); + gchar **auth_info_required, + gchar **auth_info); /* Padding for future expansion */ void (*_gtk_reserved1) (void); @@ -153,9 +154,8 @@ void gtk_print_backend_print_stream (GtkPrintBackend *pri GList * gtk_print_backend_load_modules (void); void gtk_print_backend_destroy (GtkPrintBackend *print_backend); void gtk_print_backend_set_password (GtkPrintBackend *backend, - const gchar *hostname, - const gchar *username, - const gchar *password); + gchar **auth_info_required, + gchar **auth_info); /* Backend-only functions for GtkPrintBackend */ diff --git a/gtk/gtkprintcontext.c b/gtk/gtkprintcontext.c index c280881f80..80eac79fa7 100644 --- a/gtk/gtkprintcontext.c +++ b/gtk/gtkprintcontext.c @@ -177,11 +177,11 @@ _gtk_print_context_rotate_according_to_orientation (GtkPrintContext *context) case GTK_PAGE_ORIENTATION_PORTRAIT: break; case GTK_PAGE_ORIENTATION_LANDSCAPE: - cairo_translate (cr, width, 0); + cairo_translate (cr, 0, height); cairo_matrix_init (&matrix, - 0, 1, - -1, 0, - 0, 0); + 0, -1, + 1, 0, + 0, 0); cairo_transform (cr, &matrix); break; case GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT: @@ -193,11 +193,11 @@ _gtk_print_context_rotate_according_to_orientation (GtkPrintContext *context) cairo_transform (cr, &matrix); break; case GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE: - cairo_translate (cr, 0, height); + cairo_translate (cr, width, 0); cairo_matrix_init (&matrix, - 0, -1, - 1, 0, - 0, 0); + 0, 1, + -1, 0, + 0, 0); cairo_transform (cr, &matrix); break; } diff --git a/gtk/gtkprinteroption.c b/gtk/gtkprinteroption.c index 983dc65d56..47fcd32755 100644 --- a/gtk/gtkprinteroption.c +++ b/gtk/gtkprinteroption.c @@ -63,6 +63,7 @@ static void gtk_printer_option_init (GtkPrinterOption *option) { option->value = g_strdup (""); + option->activates_default = FALSE; } static void @@ -215,6 +216,23 @@ gtk_printer_option_has_choice (GtkPrinterOption *option, return FALSE; } +void +gtk_printer_option_set_activates_default (GtkPrinterOption *option, + gboolean activates) +{ + g_return_if_fail (GTK_IS_PRINTER_OPTION (option)); + + option->activates_default = activates; +} + +gboolean +gtk_printer_option_get_activates_default (GtkPrinterOption *option) +{ + g_return_val_if_fail (GTK_IS_PRINTER_OPTION (option), FALSE); + + return option->activates_default; +} + #define __GTK_PRINTER_OPTION_C__ #include "gtkaliasdef.c" diff --git a/gtk/gtkprinteroption.h b/gtk/gtkprinteroption.h index cce6986960..f1831a31c2 100644 --- a/gtk/gtkprinteroption.h +++ b/gtk/gtkprinteroption.h @@ -70,6 +70,8 @@ struct _GtkPrinterOption char **choices; char **choices_display; + gboolean activates_default; + gboolean has_conflict; char *group; }; @@ -92,24 +94,27 @@ struct _GtkPrinterOptionClass GType gtk_printer_option_get_type (void) G_GNUC_CONST; -GtkPrinterOption *gtk_printer_option_new (const char *name, - const char *display_text, - GtkPrinterOptionType type); -void gtk_printer_option_set (GtkPrinterOption *option, - const char *value); -void gtk_printer_option_set_has_conflict (GtkPrinterOption *option, - gboolean has_conflict); -void gtk_printer_option_clear_has_conflict (GtkPrinterOption *option); -void gtk_printer_option_set_boolean (GtkPrinterOption *option, - gboolean value); -void gtk_printer_option_allocate_choices (GtkPrinterOption *option, - int num); -void gtk_printer_option_choices_from_array (GtkPrinterOption *option, - int num_choices, - char *choices[], - char *choices_display[]); -gboolean gtk_printer_option_has_choice (GtkPrinterOption *option, - const char *choice); +GtkPrinterOption *gtk_printer_option_new (const char *name, + const char *display_text, + GtkPrinterOptionType type); +void gtk_printer_option_set (GtkPrinterOption *option, + const char *value); +void gtk_printer_option_set_has_conflict (GtkPrinterOption *option, + gboolean has_conflict); +void gtk_printer_option_clear_has_conflict (GtkPrinterOption *option); +void gtk_printer_option_set_boolean (GtkPrinterOption *option, + gboolean value); +void gtk_printer_option_allocate_choices (GtkPrinterOption *option, + int num); +void gtk_printer_option_choices_from_array (GtkPrinterOption *option, + int num_choices, + char *choices[], + char *choices_display[]); +gboolean gtk_printer_option_has_choice (GtkPrinterOption *option, + const char *choice); +void gtk_printer_option_set_activates_default (GtkPrinterOption *option, + gboolean activates); +gboolean gtk_printer_option_get_activates_default (GtkPrinterOption *option); G_END_DECLS diff --git a/gtk/gtkprinteroptionwidget.c b/gtk/gtkprinteroptionwidget.c index 38cdf00801..468768fb33 100644 --- a/gtk/gtkprinteroptionwidget.c +++ b/gtk/gtkprinteroptionwidget.c @@ -767,6 +767,8 @@ construct_widgets (GtkPrinterOptionWidget *widget) case GTK_PRINTER_OPTION_TYPE_STRING: priv->entry = gtk_entry_new (); + gtk_entry_set_activates_default (GTK_ENTRY (priv->entry), + gtk_printer_option_get_activates_default (source)); gtk_widget_show (priv->entry); gtk_box_pack_start (GTK_BOX (widget), priv->entry, TRUE, TRUE, 0); g_signal_connect (priv->entry, "changed", G_CALLBACK (entry_changed_cb), widget); @@ -792,6 +794,8 @@ construct_widgets (GtkPrinterOptionWidget *widget) GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER); g_object_set (priv->combo, "local-only", FALSE, NULL); + gtk_entry_set_activates_default (GTK_ENTRY (priv->entry), + gtk_printer_option_get_activates_default (source)); label = gtk_label_new_with_mnemonic (_("_Name:")); gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); @@ -850,7 +854,7 @@ update_widgets (GtkPrinterOptionWidget *widget) switch (source->type) { case GTK_PRINTER_OPTION_TYPE_BOOLEAN: - if (strcmp (source->value, "True") == 0) + if (g_ascii_strcasecmp (source->value, "True") == 0) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->check), TRUE); else gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->check), FALSE); diff --git a/gtk/gtkprintoperation-private.h b/gtk/gtkprintoperation-private.h index 8c800eaea5..5e28007bee 100644 --- a/gtk/gtkprintoperation-private.h +++ b/gtk/gtkprintoperation-private.h @@ -56,6 +56,7 @@ struct _GtkPrintOperationPrivate guint is_sync : 1; guint support_selection : 1; guint has_selection : 1; + guint embed_page_setup : 1; GtkPageDrawingState page_drawing_state; diff --git a/gtk/gtkprintoperation-unix.c b/gtk/gtkprintoperation-unix.c index 765752b158..64b3a38e07 100644 --- a/gtk/gtkprintoperation-unix.c +++ b/gtk/gtkprintoperation-unix.c @@ -91,9 +91,26 @@ unix_start_page (GtkPrintOperation *op, (op->priv->page_position % op->priv->manual_number_up == 0)) { if (type == CAIRO_SURFACE_TYPE_PS) - cairo_ps_surface_set_size (op_unix->surface, w, h); + { + cairo_ps_surface_set_size (op_unix->surface, w, h); + cairo_ps_surface_dsc_begin_page_setup (op_unix->surface); + switch (gtk_page_setup_get_orientation (page_setup)) + { + case GTK_PAGE_ORIENTATION_PORTRAIT: + case GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT: + cairo_ps_surface_dsc_comment (op_unix->surface, "%%PageOrientation: Portrait"); + break; + + case GTK_PAGE_ORIENTATION_LANDSCAPE: + case GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE: + cairo_ps_surface_dsc_comment (op_unix->surface, "%%PageOrientation: Landscape"); + break; + } + } else if (type == CAIRO_SURFACE_TYPE_PDF) - cairo_pdf_surface_set_size (op_unix->surface, w, h); + { + cairo_pdf_surface_set_size (op_unix->surface, w, h); + } } } @@ -372,9 +389,9 @@ job_status_changed_cb (GtkPrintJob *job, static void -printer_changed_cb (GtkPrintUnixDialog *print_dialog, - GParamSpec *pspec, - gpointer user_data) +print_setup_changed_cb (GtkPrintUnixDialog *print_dialog, + GParamSpec *pspec, + gpointer user_data) { GtkPageSetup *page_setup; GtkPrintSettings *print_settings; @@ -414,10 +431,14 @@ get_print_dialog (GtkPrintOperation *op, if (priv->print_settings) gtk_print_unix_dialog_set_settings (GTK_PRINT_UNIX_DIALOG (pd), priv->print_settings); + if (priv->default_page_setup) gtk_print_unix_dialog_set_page_setup (GTK_PRINT_UNIX_DIALOG (pd), priv->default_page_setup); + gtk_print_unix_dialog_set_embed_page_setup (GTK_PRINT_UNIX_DIALOG (pd), + priv->embed_page_setup); + gtk_print_unix_dialog_set_current_page (GTK_PRINT_UNIX_DIALOG (pd), priv->current_page); @@ -446,7 +467,8 @@ get_print_dialog (GtkPrintOperation *op, gtk_print_unix_dialog_add_custom_tab (GTK_PRINT_UNIX_DIALOG (pd), priv->custom_widget, label); - g_signal_connect (pd, "notify::selected-printer", (GCallback) printer_changed_cb, op); + g_signal_connect (pd, "notify::selected-printer", (GCallback) print_setup_changed_cb, op); + g_signal_connect (pd, "notify::page-setup", (GCallback) print_setup_changed_cb, op); } return pd; @@ -477,7 +499,8 @@ static void finish_print (PrintResponseData *rdata, GtkPrinter *printer, GtkPageSetup *page_setup, - GtkPrintSettings *settings) + GtkPrintSettings *settings, + gboolean page_setup_set) { GtkPrintOperation *op = rdata->op; GtkPrintOperationPrivate *priv = op->priv; @@ -488,7 +511,9 @@ finish_print (PrintResponseData *rdata, gtk_print_operation_set_print_settings (op, settings); priv->print_context = _gtk_print_context_new (op); - if ( (page_setup != NULL) && (gtk_print_operation_get_default_page_setup (op) == NULL)) + if (page_setup != NULL && + (gtk_print_operation_get_default_page_setup (op) == NULL || + page_setup_set)) gtk_print_operation_set_default_page_setup (op, page_setup); _gtk_print_context_set_page_setup (priv->print_context, page_setup); @@ -561,6 +586,7 @@ handle_print_response (GtkWidget *dialog, GtkPrintSettings *settings = NULL; GtkPageSetup *page_setup = NULL; GtkPrinter *printer = NULL; + gboolean page_setup_set = FALSE; if (response == GTK_RESPONSE_OK) { @@ -585,11 +611,12 @@ handle_print_response (GtkWidget *dialog, { settings = gtk_print_unix_dialog_get_settings (GTK_PRINT_UNIX_DIALOG (pd)); page_setup = gtk_print_unix_dialog_get_page_setup (GTK_PRINT_UNIX_DIALOG (pd)); + page_setup_set = gtk_print_unix_dialog_get_page_setup_set (GTK_PRINT_UNIX_DIALOG (pd)); g_signal_emit_by_name (rdata->op, "custom-widget-apply", rdata->op->priv->custom_widget); } - finish_print (rdata, printer, page_setup, settings); + finish_print (rdata, printer, page_setup, settings, page_setup_set); if (settings) g_object_unref (settings); @@ -631,7 +658,7 @@ found_printer (GtkPrinter *printer, page_setup = gtk_page_setup_new (); } - finish_print (rdata, printer, page_setup, settings); + finish_print (rdata, printer, page_setup, settings, FALSE); if (settings) g_object_unref (settings); diff --git a/gtk/gtkprintoperation.c b/gtk/gtkprintoperation.c index 966417b22f..c8a85e7749 100644 --- a/gtk/gtkprintoperation.c +++ b/gtk/gtkprintoperation.c @@ -69,7 +69,11 @@ enum PROP_EXPORT_FILENAME, PROP_STATUS, PROP_STATUS_STRING, - PROP_CUSTOM_TAB_LABEL + PROP_CUSTOM_TAB_LABEL, + PROP_EMBED_PAGE_SETUP, + PROP_HAS_SELECTION, + PROP_SUPPORT_SELECTION, + PROP_N_PAGES_TO_PRINT }; static guint signals[LAST_SIGNAL] = { 0 }; @@ -165,6 +169,7 @@ gtk_print_operation_init (GtkPrintOperation *operation) priv->is_sync = FALSE; priv->support_selection = FALSE; priv->has_selection = FALSE; + priv->embed_page_setup = FALSE; priv->page_drawing_state = GTK_PAGE_DRAWING_STATE_READY; @@ -320,6 +325,15 @@ gtk_print_operation_set_property (GObject *object, case PROP_CUSTOM_TAB_LABEL: gtk_print_operation_set_custom_tab_label (op, g_value_get_string (value)); break; + case PROP_EMBED_PAGE_SETUP: + gtk_print_operation_set_embed_page_setup (op, g_value_get_boolean (value)); + break; + case PROP_HAS_SELECTION: + gtk_print_operation_set_has_selection (op, g_value_get_boolean (value)); + break; + case PROP_SUPPORT_SELECTION: + gtk_print_operation_set_support_selection (op, g_value_get_boolean (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -379,6 +393,18 @@ gtk_print_operation_get_property (GObject *object, case PROP_CUSTOM_TAB_LABEL: g_value_set_string (value, priv->custom_tab_label); break; + case PROP_EMBED_PAGE_SETUP: + g_value_set_boolean (value, priv->embed_page_setup); + break; + case PROP_HAS_SELECTION: + g_value_set_boolean (value, priv->has_selection); + break; + case PROP_SUPPORT_SELECTION: + g_value_set_boolean (value, priv->support_selection); + break; + case PROP_N_PAGES_TO_PRINT: + g_value_set_int (value, priv->nr_of_pages_to_print); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1205,7 +1231,7 @@ gtk_print_operation_class_init (GtkPrintOperationClass *class) * Since: 2.18 */ g_object_class_install_property (gobject_class, - PROP_TRACK_PRINT_STATUS, + PROP_SUPPORT_SELECTION, g_param_spec_boolean ("support-selection", P_("Support Selection"), P_("TRUE if the print operation will support print of selection."), @@ -1222,13 +1248,52 @@ gtk_print_operation_class_init (GtkPrintOperationClass *class) * Since: 2.18 */ g_object_class_install_property (gobject_class, - PROP_TRACK_PRINT_STATUS, + PROP_HAS_SELECTION, g_param_spec_boolean ("has-selection", P_("Has Selection"), P_("TRUE if a selecion exists."), FALSE, GTK_PARAM_READWRITE)); + + /** + * GtkPrintOperation:embed-page-setup: + * + * If %TRUE, page size combo box and orientation combo box are embedded into page setup page. + * + * Since: 2.18 + */ + g_object_class_install_property (gobject_class, + PROP_EMBED_PAGE_SETUP, + g_param_spec_boolean ("embed-page-setup", + P_("Embed Page Setup"), + P_("TRUE if page setup combos are embedded in GtkPrintDialog"), + FALSE, + GTK_PARAM_READWRITE)); + /** + * GtkPrintOperation:n-pages-to-print: + * + * The number of pages that will be printed. + * + * Note that this value is set during print preparation phase + * (%GTK_PRINT_STATUS_PREPARING), so this value should never be + * get before the data generation phase (%GTK_PRINT_STATUS_GENERATING_DATA). + * You can connect to the #GtkPrintOperation::status-changed signal + * and call gtk_print_operation_get_n_pages_to_print() when + * print status is %GTK_PRINT_STATUS_GENERATING_DATA. + * This is typically used to track the progress of print operation. + * + * Since: 2.18 + */ + g_object_class_install_property (gobject_class, + PROP_N_PAGES_TO_PRINT, + g_param_spec_int ("n-pages-to-print", + P_("Number of Pages To Print"), + P_("The number of pages that will be printed."), + -1, + G_MAXINT, + -1, + GTK_PARAM_READABLE)); } /** @@ -2032,6 +2097,12 @@ increment_page_sequence (PrintPagesData *data) GtkPrintOperationPrivate *priv = data->op->priv; gint inc; + if (data->total == -1) + { + data->total = 0; + return; + } + /* check whether we reached last position */ if (priv->page_position == data->last_position && !(data->collated_copies > 1 && data->collated < (data->collated_copies - 1))) @@ -2165,7 +2236,7 @@ update_progress (PrintPagesData *data) text = g_strdup (_("Preparing")); } else if (priv->status == GTK_PRINT_STATUS_GENERATING_DATA) - text = g_strdup_printf (_("Printing %d"), data->total - 1); + text = g_strdup_printf (_("Printing %d"), data->total); if (text) { @@ -2197,6 +2268,52 @@ gtk_print_operation_set_defer_drawing (GtkPrintOperation *op) priv->page_drawing_state = GTK_PAGE_DRAWING_STATE_DEFERRED_DRAWING; } +/** + * gtk_print_operation_set_embed_page_setup: + * @op: a #GtkPrintOperation + * @embed: %TRUE to embed page setup selection in the #GtkPrintDialog + * + * Embed page size combo box and orientation combo box into page setup page. + * Selected page setup is stored as default page setup in #GtkPrintOperation. + * + * Since: 2.18 + **/ +void +gtk_print_operation_set_embed_page_setup (GtkPrintOperation *op, + gboolean embed) +{ + GtkPrintOperationPrivate *priv; + + g_return_if_fail (GTK_IS_PRINT_OPERATION (op)); + + priv = op->priv; + + embed = embed != FALSE; + if (priv->embed_page_setup != embed) + { + priv->embed_page_setup = embed; + g_object_notify (G_OBJECT (op), "embed-page-setup"); + } +} + +/** + * gtk_print_operation_get_embed_page_setup: + * @op: a #GtkPrintOperation + * + * Gets the value of #GtkPrintOperation::embed-page-setup property. + * + * Returns: whether page setup selection combos are embedded + * + * Since: 2.18 + */ +gboolean +gtk_print_operation_get_embed_page_setup (GtkPrintOperation *op) +{ + g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), FALSE); + + return op->priv->embed_page_setup; +} + /** * gtk_print_operation_draw_page_finish: * @op: a #GtkPrintOperation @@ -2437,7 +2554,7 @@ common_render_page (GtkPrintOperation *op, if (priv->manual_scale != 1.0) cairo_scale (cr, priv->manual_scale, priv->manual_scale); - cairo_rotate (cr, - M_PI / 2); + cairo_rotate (cr, - G_PI / 2); } } else @@ -2549,7 +2666,7 @@ prepare_data (PrintPagesData *data) counter++; } - data->total = 0; + data->total = -1; data->collated = 0; data->uncollated = 0; @@ -2647,11 +2764,10 @@ print_pages_idle (gpointer user_data) goto out; } + increment_page_sequence (data); + if (!data->done) - { - common_render_page (data->op, data->page); - increment_page_sequence (data); - } + common_render_page (data->op, data->page); else done = priv->page_drawing_state == GTK_PAGE_DRAWING_STATE_READY; @@ -3106,5 +3222,31 @@ gtk_print_operation_get_has_selection (GtkPrintOperation *op) return op->priv->has_selection; } +/** + * gtk_print_operation_get_n_pages_to_print: + * @op: a #GtkPrintOperation + * + * Returns the number of pages that will be printed. + * + * Note that this value is set during print preparation phase + * (%GTK_PRINT_STATUS_PREPARING), so this function should never be + * called before the data generation phase (%GTK_PRINT_STATUS_GENERATING_DATA). + * You can connect to the #GtkPrintOperation::status-changed signal + * and call gtk_print_operation_get_n_pages_to_print() when + * print status is %GTK_PRINT_STATUS_GENERATING_DATA. + * This is typically used to track the progress of print operation. + * + * Returns: the number of pages that will be printed + * + * Since: 2.18 + **/ +gint +gtk_print_operation_get_n_pages_to_print (GtkPrintOperation *op) +{ + g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), -1); + + return op->priv->nr_of_pages_to_print; +} + #define __GTK_PRINT_OPERATION_C__ #include "gtkaliasdef.c" diff --git a/gtk/gtkprintoperation.h b/gtk/gtkprintoperation.h index aee3d95ec6..ef9a2879f3 100644 --- a/gtk/gtkprintoperation.h +++ b/gtk/gtkprintoperation.h @@ -184,6 +184,10 @@ gboolean gtk_print_operation_get_support_selection (GtkPrintOper void gtk_print_operation_set_has_selection (GtkPrintOperation *op, gboolean has_selection); gboolean gtk_print_operation_get_has_selection (GtkPrintOperation *op); +void gtk_print_operation_set_embed_page_setup (GtkPrintOperation *op, + gboolean embed); +gboolean gtk_print_operation_get_embed_page_setup (GtkPrintOperation *op); +gint gtk_print_operation_get_n_pages_to_print (GtkPrintOperation *op); GtkPageSetup *gtk_print_run_page_setup_dialog (GtkWindow *parent, GtkPageSetup *page_setup, diff --git a/gtk/gtkprintsettings.c b/gtk/gtkprintsettings.c index e50208017b..5c66fd69cd 100644 --- a/gtk/gtkprintsettings.c +++ b/gtk/gtkprintsettings.c @@ -1185,7 +1185,7 @@ gtk_print_settings_set_number_up (GtkPrintSettings *settings, gint gtk_print_settings_get_resolution (GtkPrintSettings *settings) { - return gtk_print_settings_get_int (settings, GTK_PRINT_SETTINGS_RESOLUTION); + return gtk_print_settings_get_int_with_default (settings, GTK_PRINT_SETTINGS_RESOLUTION, 300); } /** @@ -1224,7 +1224,7 @@ gtk_print_settings_set_resolution (GtkPrintSettings *settings, gint gtk_print_settings_get_resolution_x (GtkPrintSettings *settings) { - return gtk_print_settings_get_int (settings, GTK_PRINT_SETTINGS_RESOLUTION_X); + return gtk_print_settings_get_int_with_default (settings, GTK_PRINT_SETTINGS_RESOLUTION_X, 300); } /** @@ -1240,7 +1240,7 @@ gtk_print_settings_get_resolution_x (GtkPrintSettings *settings) gint gtk_print_settings_get_resolution_y (GtkPrintSettings *settings) { - return gtk_print_settings_get_int (settings, GTK_PRINT_SETTINGS_RESOLUTION_Y); + return gtk_print_settings_get_int_with_default (settings, GTK_PRINT_SETTINGS_RESOLUTION_Y, 300); } /** @@ -1281,7 +1281,7 @@ gtk_print_settings_set_resolution_xy (GtkPrintSettings *settings, gdouble gtk_print_settings_get_printer_lpi (GtkPrintSettings *settings) { - return gtk_print_settings_get_double (settings, GTK_PRINT_SETTINGS_PRINTER_LPI); + return gtk_print_settings_get_double_with_default (settings, GTK_PRINT_SETTINGS_PRINTER_LPI, 150.0); } /** diff --git a/gtk/gtkprintunixdialog.c b/gtk/gtkprintunixdialog.c index afd7e72f1a..5f9d8d28ac 100644 --- a/gtk/gtkprintunixdialog.c +++ b/gtk/gtkprintunixdialog.c @@ -50,16 +50,21 @@ #include "gtkeventbox.h" #include "gtkbuildable.h" +#include "gtkcustompaperunixdialog.h" #include "gtkprintbackend.h" #include "gtkprinter-private.h" #include "gtkprintunixdialog.h" #include "gtkprinteroptionwidget.h" +#include "gtkprintutils.h" #include "gtkalias.h" #include "gtkmessagedialog.h" #include "gtkbutton.h" #define EXAMPLE_PAGE_AREA_SIZE 140 +#define RULER_DISTANCE 7.5 +#define RULER_RADIUS 2 + #define GTK_PRINT_UNIX_DIALOG_GET_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_PRINT_UNIX_DIALOG, GtkPrintUnixDialogPrivate)) @@ -103,6 +108,7 @@ static void set_cell_sensitivity_func (GtkTreeViewColumn *tree_colu gpointer data); static gboolean set_active_printer (GtkPrintUnixDialog *dialog, const gchar *printer_name); +static void redraw_page_layout_preview (GtkPrintUnixDialog *dialog); /* GtkBuildable */ static void gtk_print_unix_dialog_buildable_init (GtkBuildableIface *iface); @@ -110,6 +116,27 @@ static GObject *gtk_print_unix_dialog_buildable_get_internal_child (GtkBuildabl GtkBuilder *builder, const gchar *childname); +static const gchar const common_paper_sizes[][16] = { + "na_letter", + "na_legal", + "iso_a4", + "iso_a5", + "roc_16k", + "iso_b5", + "jis_b5", + "na_number-10", + "iso_dl", + "jpn_chou3", + "na_ledger", + "iso_a3", +}; + +enum { + PAGE_SETUP_LIST_COL_PAGE_SETUP, + PAGE_SETUP_LIST_COL_IS_SEPARATOR, + PAGE_SETUP_LIST_N_COLS +}; + enum { PROP_0, PROP_PAGE_SETUP, @@ -118,7 +145,8 @@ enum { PROP_SELECTED_PRINTER, PROP_MANUAL_CAPABILITIES, PROP_SUPPORT_SELECTION, - PROP_HAS_SELECTION + PROP_HAS_SELECTION, + PROP_EMBED_PAGE_SETUP }; enum { @@ -145,6 +173,9 @@ struct GtkPrintUnixDialogPrivate GtkPageSetup *page_setup; gboolean page_setup_set; + gboolean embed_page_setup; + GtkListStore *page_setup_list; + GtkListStore *custom_paper_list; gboolean support_selection; gboolean has_selection; @@ -168,6 +199,11 @@ struct GtkPrintUnixDialogPrivate GtkWidget *print_at_entry; GtkWidget *print_hold_radio; GtkWidget *preview_button; + GtkWidget *paper_size_combo; + GtkWidget *paper_size_combo_label; + GtkWidget *orientation_combo; + GtkWidget *orientation_combo_label; + gboolean internal_page_setup_change; gboolean updating_print_at; GtkPrinterOptionWidget *pages_per_sheet; GtkPrinterOptionWidget *duplex; @@ -319,6 +355,14 @@ gtk_print_unix_dialog_class_init (GtkPrintUnixDialogClass *class) FALSE, GTK_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_EMBED_PAGE_SETUP, + g_param_spec_boolean ("embed-page-setup", + P_("Embed Page Setup"), + P_("TRUE if page setup combos are embedded in GtkPrintUnixDialog"), + FALSE, + GTK_PARAM_READWRITE)); + g_type_class_add_private (class, sizeof (GtkPrintUnixDialogPrivate)); } @@ -335,6 +379,32 @@ get_toplevel (GtkWidget *widget) return GTK_WINDOW (toplevel); } +static void +set_busy_cursor (GtkPrintUnixDialog *dialog, + gboolean busy) +{ + GtkWindow *toplevel; + GdkDisplay *display; + GdkCursor *cursor; + + toplevel = get_toplevel (GTK_WIDGET (dialog)); + if (!toplevel || !GTK_WIDGET_REALIZED (toplevel)) + return; + + display = gtk_widget_get_display (GTK_WIDGET (toplevel)); + + if (busy) + cursor = gdk_cursor_new_for_display (display, GDK_WATCH); + else + cursor = NULL; + + gdk_window_set_cursor (GTK_WIDGET (toplevel)->window, cursor); + gdk_display_flush (display); + + if (cursor) + gdk_cursor_unref (cursor); +} + static void add_custom_button_to_dialog (GtkDialog *dialog, const gchar *mnemonic_label, @@ -374,72 +444,81 @@ error_dialogs (GtkPrintUnixDialog *print_dialog, { printer = gtk_print_unix_dialog_get_selected_printer (print_dialog); - /* Shows overwrite confirmation dialog in the case of printing to file which - * already exists. */ - if (printer != NULL && gtk_printer_is_virtual (printer)) + if (printer != NULL) { - option = gtk_printer_option_set_lookup (priv->options, - "gtk-main-page-custom-input"); - - if (option != NULL && - option->type == GTK_PRINTER_OPTION_TYPE_FILESAVE) + if (priv->request_details_tag || !gtk_printer_is_accepting_jobs (printer)) { - file = g_file_new_for_uri (option->value); + g_signal_stop_emission_by_name (print_dialog, "response"); + return TRUE; + } - if (file != NULL && - g_file_query_exists (file, NULL)) + /* Shows overwrite confirmation dialog in the case of printing to file which + * already exists. */ + if (gtk_printer_is_virtual (printer)) + { + option = gtk_printer_option_set_lookup (priv->options, + "gtk-main-page-custom-input"); + + if (option != NULL && + option->type == GTK_PRINTER_OPTION_TYPE_FILESAVE) { - toplevel = get_toplevel (GTK_WIDGET (print_dialog)); + file = g_file_new_for_uri (option->value); - basename = g_file_get_basename (file); - dirname = g_file_get_parse_name (g_file_get_parent (file)); - - dialog = gtk_message_dialog_new (toplevel, - GTK_DIALOG_MODAL | - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_QUESTION, - GTK_BUTTONS_NONE, - _("A file named \"%s\" already exists. Do you want to replace it?"), - basename); - - gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), - _("The file already exists in \"%s\". Replacing it will " - "overwrite its contents."), - dirname); - - gtk_dialog_add_button (GTK_DIALOG (dialog), - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); - add_custom_button_to_dialog (GTK_DIALOG (dialog), - _("_Replace"), - GTK_STOCK_PRINT, - GTK_RESPONSE_ACCEPT); - gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog), - GTK_RESPONSE_ACCEPT, - GTK_RESPONSE_CANCEL, - -1); - gtk_dialog_set_default_response (GTK_DIALOG (dialog), - GTK_RESPONSE_ACCEPT); - - if (toplevel->group) - gtk_window_group_add_window (toplevel->group, - GTK_WINDOW (dialog)); - - response = gtk_dialog_run (GTK_DIALOG (dialog)); - - gtk_widget_destroy (dialog); - - g_free (dirname); - g_free (basename); - - if (response != GTK_RESPONSE_ACCEPT) + if (file != NULL && + g_file_query_exists (file, NULL)) { - g_signal_stop_emission_by_name (print_dialog, "response"); - g_object_unref (file); - return TRUE; - } - } + toplevel = get_toplevel (GTK_WIDGET (print_dialog)); - g_object_unref (file); + basename = g_file_get_basename (file); + dirname = g_file_get_parse_name (g_file_get_parent (file)); + + dialog = gtk_message_dialog_new (toplevel, + GTK_DIALOG_MODAL | + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_NONE, + _("A file named \"%s\" already exists. Do you want to replace it?"), + basename); + + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), + _("The file already exists in \"%s\". Replacing it will " + "overwrite its contents."), + dirname); + + gtk_dialog_add_button (GTK_DIALOG (dialog), + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); + add_custom_button_to_dialog (GTK_DIALOG (dialog), + _("_Replace"), + GTK_STOCK_PRINT, + GTK_RESPONSE_ACCEPT); + gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog), + GTK_RESPONSE_ACCEPT, + GTK_RESPONSE_CANCEL, + -1); + gtk_dialog_set_default_response (GTK_DIALOG (dialog), + GTK_RESPONSE_ACCEPT); + + if (toplevel->group) + gtk_window_group_add_window (toplevel->group, + GTK_WINDOW (dialog)); + + response = gtk_dialog_run (GTK_DIALOG (dialog)); + + gtk_widget_destroy (dialog); + + g_free (dirname); + g_free (basename); + + if (response != GTK_RESPONSE_ACCEPT) + { + g_signal_stop_emission_by_name (print_dialog, "response"); + g_object_unref (file); + return TRUE; + } + } + + g_object_unref (file); + } } } } @@ -459,6 +538,8 @@ gtk_print_unix_dialog_init (GtkPrintUnixDialog *dialog) priv->page_setup = gtk_page_setup_new (); priv->page_setup_set = FALSE; + priv->embed_page_setup = FALSE; + priv->internal_page_setup_change = FALSE; priv->support_selection = FALSE; priv->has_selection = FALSE; @@ -473,6 +554,11 @@ gtk_print_unix_dialog_init (GtkPrintUnixDialog *dialog) (GCallback) error_dialogs, NULL); + g_signal_connect (dialog, + "notify::page-setup", + (GCallback) redraw_page_layout_preview, + NULL); + priv->preview_button = gtk_button_new_from_stock (GTK_STOCK_PRINT_PREVIEW); gtk_widget_show (priv->preview_button); @@ -492,6 +578,13 @@ gtk_print_unix_dialog_init (GtkPrintUnixDialog *dialog) gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, FALSE); + priv->page_setup_list = gtk_list_store_new (PAGE_SETUP_LIST_N_COLS, + G_TYPE_OBJECT, + G_TYPE_BOOLEAN); + + priv->custom_paper_list = gtk_list_store_new (1, G_TYPE_OBJECT); + _gtk_print_load_custom_papers (priv->custom_paper_list); + populate_dialog (dialog); } @@ -503,7 +596,7 @@ gtk_print_unix_dialog_destroy (GtkPrintUnixDialog *dialog) } static void -disconnect_printer_details_request (GtkPrintUnixDialog *dialog) +disconnect_printer_details_request (GtkPrintUnixDialog *dialog, gboolean details_failed) { GtkPrintUnixDialogPrivate *priv = dialog->priv; @@ -512,6 +605,21 @@ disconnect_printer_details_request (GtkPrintUnixDialog *dialog) g_signal_handler_disconnect (priv->request_details_printer, priv->request_details_tag); priv->request_details_tag = 0; + set_busy_cursor (dialog, FALSE); + if (details_failed) + gtk_list_store_set (GTK_LIST_STORE (priv->printer_list), + g_object_get_data (G_OBJECT (priv->request_details_printer), + "gtk-print-tree-iter"), + PRINTER_LIST_COL_STATE, + _("Getting printer information failed"), + -1); + else + gtk_list_store_set (GTK_LIST_STORE (priv->printer_list), + g_object_get_data (G_OBJECT (priv->request_details_printer), + "gtk-print-tree-iter"), + PRINTER_LIST_COL_STATE, + gtk_printer_get_state_message (priv->request_details_printer), + -1); g_object_unref (priv->request_details_printer); priv->request_details_printer = NULL; } @@ -526,7 +634,7 @@ gtk_print_unix_dialog_finalize (GObject *object) GList *node; unschedule_idle_mark_conflicts (dialog); - disconnect_printer_details_request (dialog); + disconnect_printer_details_request (dialog, FALSE); if (priv->current_printer) { @@ -540,6 +648,12 @@ gtk_print_unix_dialog_finalize (GObject *object) priv->printer_list = NULL; } + if (priv->custom_paper_list) + { + g_object_unref (priv->custom_paper_list); + priv->custom_paper_list = NULL; + } + if (priv->printer_list_filter) { g_object_unref (priv->printer_list_filter); @@ -603,6 +717,12 @@ gtk_print_unix_dialog_finalize (GObject *object) g_list_free (priv->print_backends); priv->print_backends = NULL; + if (priv->page_setup_list) + { + g_object_unref (priv->page_setup_list); + priv->page_setup_list = NULL; + } + G_OBJECT_CLASS (gtk_print_unix_dialog_parent_class)->finalize (object); } @@ -826,6 +946,9 @@ gtk_print_unix_dialog_set_property (GObject *object, case PROP_HAS_SELECTION: gtk_print_unix_dialog_set_has_selection (dialog, g_value_get_boolean (value)); break; + case PROP_EMBED_PAGE_SETUP: + gtk_print_unix_dialog_set_embed_page_setup (dialog, g_value_get_boolean (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -864,6 +987,9 @@ gtk_print_unix_dialog_get_property (GObject *object, case PROP_HAS_SELECTION: g_value_set_boolean (value, priv->has_selection); break; + case PROP_EMBED_PAGE_SETUP: + g_value_set_boolean (value, priv->embed_page_setup); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1348,6 +1474,196 @@ update_dialog_from_capabilities (GtkPrintUnixDialog *dialog) gtk_tree_model_filter_refilter (priv->printer_list_filter); } +static gboolean +page_setup_is_equal (GtkPageSetup *a, + GtkPageSetup *b) +{ + return + gtk_paper_size_is_equal (gtk_page_setup_get_paper_size (a), + gtk_page_setup_get_paper_size (b)) && + gtk_page_setup_get_top_margin (a, GTK_UNIT_MM) == gtk_page_setup_get_top_margin (b, GTK_UNIT_MM) && + gtk_page_setup_get_bottom_margin (a, GTK_UNIT_MM) == gtk_page_setup_get_bottom_margin (b, GTK_UNIT_MM) && + gtk_page_setup_get_left_margin (a, GTK_UNIT_MM) == gtk_page_setup_get_left_margin (b, GTK_UNIT_MM) && + gtk_page_setup_get_right_margin (a, GTK_UNIT_MM) == gtk_page_setup_get_right_margin (b, GTK_UNIT_MM); +} + +static gboolean +page_setup_is_same_size (GtkPageSetup *a, + GtkPageSetup *b) +{ + return gtk_paper_size_is_equal (gtk_page_setup_get_paper_size (a), + gtk_page_setup_get_paper_size (b)); +} + +static gboolean +set_paper_size (GtkPrintUnixDialog *dialog, + GtkPageSetup *page_setup, + gboolean size_only, + gboolean add_item) +{ + GtkPrintUnixDialogPrivate *priv = dialog->priv; + GtkTreeModel *model; + GtkTreeIter iter; + GtkPageSetup *list_page_setup; + + if (!priv->internal_page_setup_change) + return TRUE; + + if (page_setup == NULL) + return FALSE; + + model = GTK_TREE_MODEL (priv->page_setup_list); + + if (gtk_tree_model_get_iter_first (model, &iter)) + { + do + { + gtk_tree_model_get (GTK_TREE_MODEL (priv->page_setup_list), &iter, + PAGE_SETUP_LIST_COL_PAGE_SETUP, &list_page_setup, -1); + if (list_page_setup == NULL) + continue; + + if ((size_only && page_setup_is_same_size (page_setup, list_page_setup)) || + (!size_only && page_setup_is_equal (page_setup, list_page_setup))) + { + gtk_combo_box_set_active_iter (GTK_COMBO_BOX (priv->paper_size_combo), + &iter); + gtk_combo_box_set_active (GTK_COMBO_BOX (priv->orientation_combo), + gtk_page_setup_get_orientation (page_setup)); + g_object_unref (list_page_setup); + return TRUE; + } + + g_object_unref (list_page_setup); + + } while (gtk_tree_model_iter_next (model, &iter)); + } + + if (add_item) + { + gtk_list_store_append (priv->page_setup_list, &iter); + gtk_list_store_set (priv->page_setup_list, &iter, + PAGE_SETUP_LIST_COL_IS_SEPARATOR, TRUE, + -1); + gtk_list_store_append (priv->page_setup_list, &iter); + gtk_list_store_set (priv->page_setup_list, &iter, + PAGE_SETUP_LIST_COL_PAGE_SETUP, page_setup, + -1); + gtk_combo_box_set_active_iter (GTK_COMBO_BOX (priv->paper_size_combo), + &iter); + gtk_combo_box_set_active (GTK_COMBO_BOX (priv->orientation_combo), + gtk_page_setup_get_orientation (page_setup)); + return TRUE; + } + + return FALSE; +} + +static void +fill_custom_paper_sizes (GtkPrintUnixDialog *dialog) +{ + GtkPrintUnixDialogPrivate *priv = dialog->priv; + GtkTreeIter iter, paper_iter; + GtkTreeModel *model; + + model = GTK_TREE_MODEL (priv->custom_paper_list); + if (gtk_tree_model_get_iter_first (model, &iter)) + { + gtk_list_store_append (priv->page_setup_list, &paper_iter); + gtk_list_store_set (priv->page_setup_list, &paper_iter, + PAGE_SETUP_LIST_COL_IS_SEPARATOR, TRUE, + -1); + do + { + GtkPageSetup *page_setup; + gtk_tree_model_get (model, &iter, 0, &page_setup, -1); + + gtk_list_store_append (priv->page_setup_list, &paper_iter); + gtk_list_store_set (priv->page_setup_list, &paper_iter, + PAGE_SETUP_LIST_COL_PAGE_SETUP, page_setup, + -1); + + g_object_unref (page_setup); + } while (gtk_tree_model_iter_next (model, &iter)); + } + + gtk_list_store_append (priv->page_setup_list, &paper_iter); + gtk_list_store_set (priv->page_setup_list, &paper_iter, + PAGE_SETUP_LIST_COL_IS_SEPARATOR, TRUE, + -1); + gtk_list_store_append (priv->page_setup_list, &paper_iter); + gtk_list_store_set (priv->page_setup_list, &paper_iter, + PAGE_SETUP_LIST_COL_PAGE_SETUP, NULL, + -1); +} + +static void +fill_paper_sizes (GtkPrintUnixDialog *dialog, + GtkPrinter *printer) +{ + GtkPrintUnixDialogPrivate *priv = dialog->priv; + GList *list, *l; + GtkPageSetup *page_setup; + GtkPaperSize *paper_size; + GtkTreeIter iter; + gint i; + + gtk_list_store_clear (priv->page_setup_list); + + if (printer == NULL || (list = gtk_printer_list_papers (printer)) == NULL) + { + for (i = 0; i < G_N_ELEMENTS (common_paper_sizes); i++) + { + page_setup = gtk_page_setup_new (); + paper_size = gtk_paper_size_new (common_paper_sizes[i]); + gtk_page_setup_set_paper_size_and_default_margins (page_setup, paper_size); + gtk_paper_size_free (paper_size); + + gtk_list_store_append (priv->page_setup_list, &iter); + gtk_list_store_set (priv->page_setup_list, &iter, + PAGE_SETUP_LIST_COL_PAGE_SETUP, page_setup, + -1); + g_object_unref (page_setup); + } + } + else + { + for (l = list; l != NULL; l = l->next) + { + page_setup = l->data; + gtk_list_store_append (priv->page_setup_list, &iter); + gtk_list_store_set (priv->page_setup_list, &iter, + PAGE_SETUP_LIST_COL_PAGE_SETUP, page_setup, + -1); + g_object_unref (page_setup); + } + g_list_free (list); + } + + fill_custom_paper_sizes (dialog); +} + +static void +update_paper_sizes (GtkPrintUnixDialog *dialog) +{ + GtkPageSetup *current_page_setup = NULL; + GtkPrinter *printer; + + printer = gtk_print_unix_dialog_get_selected_printer (dialog); + + fill_paper_sizes (dialog, printer); + + current_page_setup = gtk_page_setup_copy (gtk_print_unix_dialog_get_page_setup (dialog)); + + if (current_page_setup) + { + if (!set_paper_size (dialog, current_page_setup, FALSE, FALSE)) + set_paper_size (dialog, current_page_setup, TRUE, TRUE); + + g_object_unref (current_page_setup); + } +} + static void mark_conflicts (GtkPrintUnixDialog *dialog) { @@ -1473,7 +1789,7 @@ printer_details_acquired (GtkPrinter *printer, { GtkPrintUnixDialogPrivate *priv = dialog->priv; - disconnect_printer_details_request (dialog); + disconnect_printer_details_request (dialog, !success); if (success) { @@ -1501,7 +1817,7 @@ selected_printer_changed (GtkTreeSelection *selection, priv->waiting_for_printer = NULL; } - disconnect_printer_details_request (dialog); + disconnect_printer_details_request (dialog, FALSE); printer = NULL; if (gtk_tree_selection_get_selected (selection, NULL, &filter_iter)) @@ -1540,6 +1856,11 @@ selected_printer_changed (GtkTreeSelection *selection, /* take the reference */ priv->request_details_printer = printer; gtk_printer_request_details (printer); + set_busy_cursor (dialog, TRUE); + gtk_list_store_set (GTK_LIST_STORE (priv->printer_list), + g_object_get_data (G_OBJECT (printer), "gtk-print-tree-iter"), + PRINTER_LIST_COL_STATE, _("Getting printer information..."), + -1); return; } @@ -1581,6 +1902,9 @@ selected_printer_changed (GtkTreeSelection *selection, if (!page_setup) page_setup = gtk_page_setup_new (); + if (page_setup && priv->page_setup) + gtk_page_setup_set_orientation (page_setup, gtk_page_setup_get_orientation (priv->page_setup)); + g_object_unref (priv->page_setup); priv->page_setup = page_setup; } @@ -1598,6 +1922,10 @@ selected_printer_changed (GtkTreeSelection *selection, update_dialog_from_settings (dialog); update_dialog_from_capabilities (dialog); + priv->internal_page_setup_change = TRUE; + update_paper_sizes (dialog); + priv->internal_page_setup_change = FALSE; + g_object_notify ( G_OBJECT(dialog), "selected-printer"); } @@ -2260,6 +2588,11 @@ draw_page_cb (GtkWidget *widget, gint start_x, end_x, start_y, end_y; gint dx, dy; gboolean horizontal; + GtkPageSetup *page_setup; + gdouble paper_width, paper_height; + gdouble pos_x, pos_y; + gint pages_per_sheet; + gboolean ltr = TRUE; orientation = gtk_page_setup_get_orientation (priv->page_setup); landscape = @@ -2270,14 +2603,49 @@ draw_page_cb (GtkWidget *widget, cr = gdk_cairo_create (widget->window); - cairo_translate (cr, widget->allocation.x, widget->allocation.y); + cairo_save (cr); - ratio = G_SQRT2; + page_setup = gtk_print_unix_dialog_get_page_setup (dialog); - w = (EXAMPLE_PAGE_AREA_SIZE - 3) / ratio; - h = w * ratio; + if (page_setup != NULL) + { + if (!landscape) + { + paper_width = gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_MM); + paper_height = gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_MM); + } + else + { + paper_width = gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_MM); + paper_height = gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_MM); + } - switch (dialog_get_pages_per_sheet (dialog)) + if (paper_width < paper_height) + { + h = EXAMPLE_PAGE_AREA_SIZE - 3; + w = (paper_height != 0) ? h * paper_width / paper_height : 0; + } + else + { + w = EXAMPLE_PAGE_AREA_SIZE - 3; + h = (paper_width != 0) ? w * paper_height / paper_width : 0; + } + + if (paper_width == 0) + w = 0; + + if (paper_height == 0) + h = 0; + } + else + { + ratio = G_SQRT2; + w = (EXAMPLE_PAGE_AREA_SIZE - 3) / ratio; + h = EXAMPLE_PAGE_AREA_SIZE - 3; + } + + pages_per_sheet = dialog_get_pages_per_sheet (dialog); + switch (pages_per_sheet) { default: case 1: @@ -2313,6 +2681,11 @@ draw_page_cb (GtkWidget *widget, pages_y = tmp; } + pos_x = widget->allocation.x + (widget->allocation.width - w) / 2; + pos_y = widget->allocation.y + (widget->allocation.height - h) / 2 - 10; + color = &widget->style->text[GTK_STATE_NORMAL]; + cairo_translate (cr, pos_x, pos_y); + shadow_offset = 3; color = &widget->style->text[GTK_STATE_NORMAL]; @@ -2324,7 +2697,7 @@ draw_page_cb (GtkWidget *widget, cairo_rectangle (cr, 1, 1, w, h); cairo_fill (cr); cairo_set_line_width (cr, 1.0); - cairo_rectangle (cr, 0.5, 0.5, w+1, h+1); + cairo_rectangle (cr, 0.5, 0.5, w + 1, h + 1); gdk_cairo_set_source_color (cr, &widget->style->text[GTK_STATE_NORMAL]); cairo_stroke (cr); @@ -2338,7 +2711,12 @@ draw_page_cb (GtkWidget *widget, font = pango_font_description_new (); pango_font_description_set_family (font, "sans"); - pango_font_description_set_absolute_size (font, page_height * 0.4 * PANGO_SCALE); + + if (page_height > 0) + pango_font_description_set_absolute_size (font, page_height * 0.4 * PANGO_SCALE); + else + pango_font_description_set_absolute_size (font, 1); + pango_layout_set_font_description (layout, font); pango_font_description_free (font); @@ -2460,6 +2838,135 @@ draw_page_cb (GtkWidget *widget, } g_object_unref (layout); + + if (page_setup != NULL) + { + pos_x += 1; + pos_y += 1; + + if (pages_per_sheet == 2 || pages_per_sheet == 6) + { + paper_width = gtk_page_setup_get_paper_height (page_setup, _gtk_print_get_default_user_units ()); + paper_height = gtk_page_setup_get_paper_width (page_setup, _gtk_print_get_default_user_units ()); + } + else + { + paper_width = gtk_page_setup_get_paper_width (page_setup, _gtk_print_get_default_user_units ()); + paper_height = gtk_page_setup_get_paper_height (page_setup, _gtk_print_get_default_user_units ()); + } + + cairo_restore (cr); + cairo_save (cr); + + layout = pango_cairo_create_layout (cr); + + font = pango_font_description_new (); + pango_font_description_set_family (font, "sans"); + + PangoContext *pango_c = NULL; + PangoFontDescription *pango_f = NULL; + gint font_size = 12 * PANGO_SCALE; + + pango_c = gtk_widget_get_pango_context (widget); + if (pango_c != NULL) + { + pango_f = pango_context_get_font_description (pango_c); + if (pango_f != NULL) + font_size = pango_font_description_get_size (pango_f); + } + + pango_font_description_set_size (font, font_size); + pango_layout_set_font_description (layout, font); + pango_font_description_free (font); + + pango_layout_set_width (layout, -1); + pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER); + + if (_gtk_print_get_default_user_units () == GTK_UNIT_MM) + text = g_strdup_printf ("%.1f mm", paper_height); + else + text = g_strdup_printf ("%.2f inch", paper_height); + + pango_layout_set_text (layout, text, -1); + g_free (text); + pango_layout_get_size (layout, &layout_w, &layout_h); + + ltr = gtk_widget_get_direction (GTK_WIDGET (dialog)) == GTK_TEXT_DIR_LTR; + + if (ltr) + cairo_translate (cr, pos_x - layout_w / PANGO_SCALE - 2 * RULER_DISTANCE, + widget->allocation.y + (widget->allocation.height - layout_h / PANGO_SCALE) / 2); + else + cairo_translate (cr, pos_x + w + shadow_offset + 2 * RULER_DISTANCE, + widget->allocation.y + (widget->allocation.height - layout_h / PANGO_SCALE) / 2); + + pango_cairo_show_layout (cr, layout); + + cairo_restore (cr); + cairo_save (cr); + + if (_gtk_print_get_default_user_units () == GTK_UNIT_MM) + text = g_strdup_printf ("%.1f mm", paper_width); + else + text = g_strdup_printf ("%.2f inch", paper_width); + + pango_layout_set_text (layout, text, -1); + g_free (text); + pango_layout_get_size (layout, &layout_w, &layout_h); + + cairo_translate (cr, widget->allocation.x + (widget->allocation.width - layout_w / PANGO_SCALE) / 2, + pos_y + h + shadow_offset + 2 * RULER_DISTANCE); + + pango_cairo_show_layout (cr, layout); + + g_object_unref (layout); + + cairo_restore (cr); + + cairo_set_line_width (cr, 1); + + if (ltr) + { + cairo_move_to (cr, pos_x - RULER_DISTANCE, pos_y); + cairo_line_to (cr, pos_x - RULER_DISTANCE, pos_y + h); + cairo_stroke (cr); + + cairo_move_to (cr, pos_x - RULER_DISTANCE - RULER_RADIUS, pos_y - 0.5); + cairo_line_to (cr, pos_x - RULER_DISTANCE + RULER_RADIUS, pos_y - 0.5); + cairo_stroke (cr); + + cairo_move_to (cr, pos_x - RULER_DISTANCE - RULER_RADIUS, pos_y + h + 0.5); + cairo_line_to (cr, pos_x - RULER_DISTANCE + RULER_RADIUS, pos_y + h + 0.5); + cairo_stroke (cr); + } + else + { + cairo_move_to (cr, pos_x + w + shadow_offset + RULER_DISTANCE, pos_y); + cairo_line_to (cr, pos_x + w + shadow_offset + RULER_DISTANCE, pos_y + h); + cairo_stroke (cr); + + cairo_move_to (cr, pos_x + w + shadow_offset + RULER_DISTANCE - RULER_RADIUS, pos_y - 0.5); + cairo_line_to (cr, pos_x + w + shadow_offset + RULER_DISTANCE + RULER_RADIUS, pos_y - 0.5); + cairo_stroke (cr); + + cairo_move_to (cr, pos_x + w + shadow_offset + RULER_DISTANCE - RULER_RADIUS, pos_y + h + 0.5); + cairo_line_to (cr, pos_x + w + shadow_offset + RULER_DISTANCE + RULER_RADIUS, pos_y + h + 0.5); + cairo_stroke (cr); + } + + cairo_move_to (cr, pos_x, pos_y + h + shadow_offset + RULER_DISTANCE); + cairo_line_to (cr, pos_x + w, pos_y + h + shadow_offset + RULER_DISTANCE); + cairo_stroke (cr); + + cairo_move_to (cr, pos_x - 0.5, pos_y + h + shadow_offset + RULER_DISTANCE - RULER_RADIUS); + cairo_line_to (cr, pos_x - 0.5, pos_y + h + shadow_offset + RULER_DISTANCE + RULER_RADIUS); + cairo_stroke (cr); + + cairo_move_to (cr, pos_x + w + 0.5, pos_y + h + shadow_offset + RULER_DISTANCE - RULER_RADIUS); + cairo_line_to (cr, pos_x + w + 0.5, pos_y + h + shadow_offset + RULER_DISTANCE + RULER_RADIUS); + cairo_stroke (cr); + } + cairo_destroy (cr); return TRUE; @@ -2609,6 +3116,156 @@ update_number_up_layout (GtkPrintUnixDialog *dialog) (dialog_get_pages_per_sheet (dialog) > 1)); } +static void +custom_paper_dialog_response_cb (GtkDialog *custom_paper_dialog, + gint response_id, + gpointer user_data) +{ + GtkPrintUnixDialog *print_dialog = GTK_PRINT_UNIX_DIALOG (user_data); + GtkPrintUnixDialogPrivate *priv = print_dialog->priv; + GtkTreeModel *model; + GtkTreeIter iter; + + _gtk_print_load_custom_papers (priv->custom_paper_list); + + priv->internal_page_setup_change = TRUE; + update_paper_sizes (print_dialog); + priv->internal_page_setup_change = FALSE; + + if (priv->page_setup_set) + { + model = GTK_TREE_MODEL (priv->custom_paper_list); + if (gtk_tree_model_get_iter_first (model, &iter)) + { + do + { + GtkPageSetup *page_setup; + gtk_tree_model_get (model, &iter, 0, &page_setup, -1); + + if (page_setup && + g_strcmp0 (gtk_paper_size_get_display_name (gtk_page_setup_get_paper_size (page_setup)), + gtk_paper_size_get_display_name (gtk_page_setup_get_paper_size (priv->page_setup))) == 0) + gtk_print_unix_dialog_set_page_setup (print_dialog, page_setup); + + g_object_unref (page_setup); + } while (gtk_tree_model_iter_next (model, &iter)); + } + } + + gtk_widget_destroy (GTK_WIDGET (custom_paper_dialog)); +} + +static void +orientation_changed (GtkComboBox *combo_box, + GtkPrintUnixDialog *dialog) +{ + GtkPrintUnixDialogPrivate *priv = dialog->priv; + GtkPageOrientation orientation; + GtkPageSetup *page_setup; + + if (priv->internal_page_setup_change) + return; + + orientation = (GtkPageOrientation) gtk_combo_box_get_active (GTK_COMBO_BOX (priv->orientation_combo)); + + if (priv->page_setup) + { + page_setup = gtk_page_setup_copy (priv->page_setup); + if (page_setup) + gtk_page_setup_set_orientation (page_setup, orientation); + + gtk_print_unix_dialog_set_page_setup (dialog, page_setup); + } + + redraw_page_layout_preview (dialog); +} + +static void +paper_size_changed (GtkComboBox *combo_box, + GtkPrintUnixDialog *dialog) +{ + GtkPrintUnixDialogPrivate *priv = dialog->priv; + GtkTreeIter iter; + GtkPageSetup *page_setup, *last_page_setup; + GtkPageOrientation orientation; + + if (priv->internal_page_setup_change) + return; + + if (gtk_combo_box_get_active_iter (combo_box, &iter)) + { + gtk_tree_model_get (gtk_combo_box_get_model (combo_box), + &iter, PAGE_SETUP_LIST_COL_PAGE_SETUP, &page_setup, -1); + + if (page_setup == NULL) + { + GtkWidget *custom_paper_dialog; + + /* Change from "manage" menu item to last value */ + if (priv->page_setup) + last_page_setup = g_object_ref (priv->page_setup); + else + last_page_setup = gtk_page_setup_new (); /* "good" default */ + + if (!set_paper_size (dialog, last_page_setup, FALSE, FALSE)) + set_paper_size (dialog, last_page_setup, TRUE, TRUE); + g_object_unref (last_page_setup); + + /* And show the custom paper dialog */ + custom_paper_dialog = _gtk_custom_paper_unix_dialog_new (GTK_WINDOW (dialog), _("Manage Custom Sizes")); + g_signal_connect (custom_paper_dialog, "response", G_CALLBACK (custom_paper_dialog_response_cb), dialog); + gtk_window_present (GTK_WINDOW (custom_paper_dialog)); + + return; + } + + if (priv->page_setup) + orientation = gtk_page_setup_get_orientation (priv->page_setup); + else + orientation = GTK_PAGE_ORIENTATION_PORTRAIT; + + gtk_page_setup_set_orientation (page_setup, orientation); + gtk_print_unix_dialog_set_page_setup (dialog, page_setup); + + g_object_unref (page_setup); + } + + redraw_page_layout_preview (dialog); +} + +static gboolean +paper_size_row_is_separator (GtkTreeModel *model, + GtkTreeIter *iter, + gpointer data) +{ + gboolean separator; + + gtk_tree_model_get (model, iter, PAGE_SETUP_LIST_COL_IS_SEPARATOR, &separator, -1); + return separator; +} + +static void +page_name_func (GtkCellLayout *cell_layout, + GtkCellRenderer *cell, + GtkTreeModel *tree_model, + GtkTreeIter *iter, + gpointer data) +{ + GtkPageSetup *page_setup; + GtkPaperSize *paper_size; + + gtk_tree_model_get (tree_model, iter, + PAGE_SETUP_LIST_COL_PAGE_SETUP, &page_setup, -1); + if (page_setup) + { + paper_size = gtk_page_setup_get_paper_size (page_setup); + g_object_set (cell, "text", gtk_paper_size_get_display_name (paper_size), NULL); + g_object_unref (page_setup); + } + else + g_object_set (cell, "text", _("Manage Custom Sizes..."), NULL); +} + static void create_page_setup_page (GtkPrintUnixDialog *dialog) { @@ -2616,6 +3273,7 @@ create_page_setup_page (GtkPrintUnixDialog *dialog) GtkWidget *main_vbox, *label, *hbox, *hbox2; GtkWidget *frame, *table, *widget; GtkWidget *combo, *spinbutton, *draw; + GtkCellRenderer *cell; main_vbox = gtk_vbox_new (FALSE, 18); gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12); @@ -2776,6 +3434,55 @@ create_page_setup_page (GtkPrintUnixDialog *dialog) 0, 0); gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget); + + label = gtk_label_new_with_mnemonic (_("_Paper size:")); + priv->paper_size_combo_label = GTK_WIDGET (label); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_widget_show (label); + gtk_table_attach (GTK_TABLE (table), label, + 0, 1, 3, 4, GTK_FILL, 0, + 0, 0); + + combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (priv->page_setup_list)); + priv->paper_size_combo = GTK_WIDGET (combo); + gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (combo), + paper_size_row_is_separator, NULL, NULL); + cell = gtk_cell_renderer_text_new (); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), cell, TRUE); + gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combo), cell, + page_name_func, NULL, NULL); + gtk_table_attach (GTK_TABLE (table), combo, + 1, 2, 3, 4, GTK_FILL, 0, + 0, 0); + gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo); + gtk_widget_set_sensitive (combo, FALSE); + gtk_widget_show (combo); + + + label = gtk_label_new_with_mnemonic (_("Or_ientation:")); + priv->orientation_combo_label = GTK_WIDGET (label); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_widget_show (label); + gtk_table_attach (GTK_TABLE (table), label, + 0, 1, 4, 5, + GTK_FILL, 0, 0, 0); + + combo = gtk_combo_box_new_text (); + priv->orientation_combo = GTK_WIDGET (combo); + gtk_table_attach (GTK_TABLE (table), combo, + 1, 2, 4, 5, GTK_FILL, 0, + 0, 0); + gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo); + /* In enum order */ + gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Portrait")); + gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Landscape")); + gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Reverse portrait")); + gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Reverse landscape")); + gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0); + gtk_widget_set_sensitive (combo, FALSE); + gtk_widget_show (combo); + + /* Add the page layout preview */ hbox2 = gtk_hbox_new (FALSE, 0); gtk_widget_show (hbox2); @@ -2784,7 +3491,7 @@ create_page_setup_page (GtkPrintUnixDialog *dialog) draw = gtk_drawing_area_new (); GTK_WIDGET_SET_FLAGS (draw, GTK_NO_WINDOW); priv->page_layout_preview = draw; - gtk_widget_set_size_request (draw, 200, 200); + gtk_widget_set_size_request (draw, 350, 200); g_signal_connect (draw, "expose-event", G_CALLBACK (draw_page_cb), dialog); gtk_widget_show (draw); @@ -3192,6 +3899,24 @@ gtk_print_unix_dialog_get_page_setup (GtkPrintUnixDialog *dialog) return dialog->priv->page_setup; } +/** + * gtk_print_unix_dialog_get_page_setup_set: + * @dialog: a #GtkPrintUnixDialog + * + * Gets the page setup that is used by the #GtkPrintUnixDialog. + * + * Returns: whether a page setup was set by user. + * + * Since: 2.18 + */ +gboolean +gtk_print_unix_dialog_get_page_setup_set (GtkPrintUnixDialog *dialog) +{ + g_return_val_if_fail (GTK_IS_PRINT_UNIX_DIALOG (dialog), FALSE); + + return dialog->priv->page_setup_set; +} + /** * gtk_print_unix_dialog_set_current_page: * @dialog: a #GtkPrintUnixDialog @@ -3620,5 +4345,73 @@ gtk_print_unix_dialog_get_has_selection (GtkPrintUnixDialog *dialog) return dialog->priv->has_selection; } +/** + * gtk_print_unix_dialog_set_embed_page_setup + * @dialog: a #GtkPrintUnixDialog + * @embed: embed page setup selection + * + * Embed page size combo box and orientation combo box into page setup page. + * + * Since: 2.18 + */ +void +gtk_print_unix_dialog_set_embed_page_setup (GtkPrintUnixDialog *dialog, + gboolean embed) +{ + GtkPrintUnixDialogPrivate *priv; + + g_return_if_fail (GTK_IS_PRINT_UNIX_DIALOG (dialog)); + + priv = dialog->priv; + + embed = embed != FALSE; + if (priv->embed_page_setup != embed) + { + priv->embed_page_setup = embed; + + gtk_widget_set_sensitive (priv->paper_size_combo, priv->embed_page_setup); + gtk_widget_set_sensitive (priv->orientation_combo, priv->embed_page_setup); + + if (priv->embed_page_setup) + { + if (priv->paper_size_combo != NULL) + g_signal_connect (priv->paper_size_combo, "changed", G_CALLBACK (paper_size_changed), dialog); + + if (priv->orientation_combo) + g_signal_connect (priv->orientation_combo, "changed", G_CALLBACK (orientation_changed), dialog); + } + else + { + if (priv->paper_size_combo != NULL) + g_signal_handlers_disconnect_by_func (priv->paper_size_combo, G_CALLBACK (paper_size_changed), dialog); + + if (priv->orientation_combo) + g_signal_handlers_disconnect_by_func (priv->orientation_combo, G_CALLBACK (orientation_changed), dialog); + } + + priv->internal_page_setup_change = TRUE; + update_paper_sizes (dialog); + priv->internal_page_setup_change = FALSE; + } +} + +/** + * gtk_print_unix_dialog_get_embed_page_setup: + * @dialog: a #GtkPrintUnixDialog + * + * Gets the value of #GtkPrintUnixDialog::embed-page-setup property. + * + * Returns: whether there is a selection + * + * Since: 2.18 + */ +gboolean +gtk_print_unix_dialog_get_embed_page_setup (GtkPrintUnixDialog *dialog) +{ + g_return_val_if_fail (GTK_IS_PRINT_UNIX_DIALOG (dialog), FALSE); + + return dialog->priv->embed_page_setup; +} + #define __GTK_PRINT_UNIX_DIALOG_C__ #include "gtkaliasdef.c" diff --git a/gtk/gtkprintunixdialog.h b/gtk/gtkprintunixdialog.h index 0d7efccfc3..4ff22e4ed8 100644 --- a/gtk/gtkprintunixdialog.h +++ b/gtk/gtkprintunixdialog.h @@ -64,25 +64,25 @@ struct _GtkPrintUnixDialogClass void (*_gtk_reserved7) (void); }; -GType gtk_print_unix_dialog_get_type (void) G_GNUC_CONST; -GtkWidget * gtk_print_unix_dialog_new (const gchar *title, - GtkWindow *parent); +GType gtk_print_unix_dialog_get_type (void) G_GNUC_CONST; +GtkWidget * gtk_print_unix_dialog_new (const gchar *title, + GtkWindow *parent); -void gtk_print_unix_dialog_set_page_setup (GtkPrintUnixDialog *dialog, - GtkPageSetup *page_setup); -GtkPageSetup * gtk_print_unix_dialog_get_page_setup (GtkPrintUnixDialog *dialog); -void gtk_print_unix_dialog_set_current_page (GtkPrintUnixDialog *dialog, - gint current_page); -gint gtk_print_unix_dialog_get_current_page (GtkPrintUnixDialog *dialog); -void gtk_print_unix_dialog_set_settings (GtkPrintUnixDialog *dialog, - GtkPrintSettings *settings); -GtkPrintSettings *gtk_print_unix_dialog_get_settings (GtkPrintUnixDialog *dialog); -GtkPrinter * gtk_print_unix_dialog_get_selected_printer (GtkPrintUnixDialog *dialog); -void gtk_print_unix_dialog_add_custom_tab (GtkPrintUnixDialog *dialog, - GtkWidget *child, - GtkWidget *tab_label); -void gtk_print_unix_dialog_set_manual_capabilities (GtkPrintUnixDialog *dialog, - GtkPrintCapabilities capabilities); +void gtk_print_unix_dialog_set_page_setup (GtkPrintUnixDialog *dialog, + GtkPageSetup *page_setup); +GtkPageSetup * gtk_print_unix_dialog_get_page_setup (GtkPrintUnixDialog *dialog); +void gtk_print_unix_dialog_set_current_page (GtkPrintUnixDialog *dialog, + gint current_page); +gint gtk_print_unix_dialog_get_current_page (GtkPrintUnixDialog *dialog); +void gtk_print_unix_dialog_set_settings (GtkPrintUnixDialog *dialog, + GtkPrintSettings *settings); +GtkPrintSettings * gtk_print_unix_dialog_get_settings (GtkPrintUnixDialog *dialog); +GtkPrinter * gtk_print_unix_dialog_get_selected_printer (GtkPrintUnixDialog *dialog); +void gtk_print_unix_dialog_add_custom_tab (GtkPrintUnixDialog *dialog, + GtkWidget *child, + GtkWidget *tab_label); +void gtk_print_unix_dialog_set_manual_capabilities (GtkPrintUnixDialog *dialog, + GtkPrintCapabilities capabilities); GtkPrintCapabilities gtk_print_unix_dialog_get_manual_capabilities (GtkPrintUnixDialog *dialog); void gtk_print_unix_dialog_set_support_selection (GtkPrintUnixDialog *dialog, gboolean support_selection); @@ -90,6 +90,10 @@ gboolean gtk_print_unix_dialog_get_support_selection (GtkPrintUnix void gtk_print_unix_dialog_set_has_selection (GtkPrintUnixDialog *dialog, gboolean has_selection); gboolean gtk_print_unix_dialog_get_has_selection (GtkPrintUnixDialog *dialog); +void gtk_print_unix_dialog_set_embed_page_setup (GtkPrintUnixDialog *dialog, + gboolean embed); +gboolean gtk_print_unix_dialog_get_embed_page_setup (GtkPrintUnixDialog *dialog); +gboolean gtk_print_unix_dialog_get_page_setup_set (GtkPrintUnixDialog *dialog); G_END_DECLS diff --git a/gtk/gtkradiobutton.c b/gtk/gtkradiobutton.c index 0d7277846b..f07113fe22 100644 --- a/gtk/gtkradiobutton.c +++ b/gtk/gtkradiobutton.c @@ -486,7 +486,7 @@ gtk_radio_button_focus (GtkWidget *widget, { GtkWidget *child = tmp_list->data; - if (GTK_WIDGET_REALIZED (child) && GTK_WIDGET_IS_SENSITIVE (child)) + if (GTK_WIDGET_MAPPED (child) && GTK_WIDGET_IS_SENSITIVE (child)) { new_focus = child; break; @@ -522,7 +522,7 @@ gtk_radio_button_focus (GtkWidget *widget, { GtkWidget *child = tmp_list->data; - if (GTK_WIDGET_REALIZED (child) && GTK_WIDGET_IS_SENSITIVE (child)) + if (GTK_WIDGET_MAPPED (child) && GTK_WIDGET_IS_SENSITIVE (child)) { new_focus = child; break; diff --git a/gtk/gtkrange.c b/gtk/gtkrange.c index ce4e5e4282..17c0d6f43a 100644 --- a/gtk/gtkrange.c +++ b/gtk/gtkrange.c @@ -843,6 +843,52 @@ gtk_range_get_inverted (GtkRange *range) return range->inverted; } +/** + * gtk_range_set_flippable: + * @range: a #GtkRange + * @flippable: %TRUE to make the range flippable + * + * If a range is flippable, it will switch its direction if it is + * horizontal and its direction is %GTK_TEXT_DIR_RTL. + * + * See gtk_widget_get_direction(). + * + * Since: 2.18 + **/ +void +gtk_range_set_flippable (GtkRange *range, + gboolean flippable) +{ + g_return_if_fail (GTK_IS_RANGE (range)); + + flippable = flippable ? TRUE : FALSE; + + if (flippable != range->flippable) + { + range->flippable = flippable; + + gtk_widget_queue_draw (GTK_WIDGET (range)); + } +} + +/** + * gtk_range_get_flippable: + * @range: a #GtkRange + * + * Gets the value set by gtk_range_set_flippable(). + * + * Return value: %TRUE if the range is flippable + * + * Since: 2.18 + **/ +gboolean +gtk_range_get_flippable (GtkRange *range) +{ + g_return_val_if_fail (GTK_IS_RANGE (range), FALSE); + + return range->flippable; +} + /** * gtk_range_set_lower_stepper_sensitivity: * @range: a #GtkRange diff --git a/gtk/gtkrange.h b/gtk/gtkrange.h index f7f3b96aa7..268a5223e1 100644 --- a/gtk/gtkrange.h +++ b/gtk/gtkrange.h @@ -147,6 +147,10 @@ void gtk_range_set_inverted (GtkRange *range gboolean setting); gboolean gtk_range_get_inverted (GtkRange *range); +void gtk_range_set_flippable (GtkRange *range, + gboolean flippable); +gboolean gtk_range_get_flippable (GtkRange *range); + void gtk_range_set_lower_stepper_sensitivity (GtkRange *range, GtkSensitivityType sensitivity); GtkSensitivityType gtk_range_get_lower_stepper_sensitivity (GtkRange *range); diff --git a/gtk/gtkscale.c b/gtk/gtkscale.c index 87aa469da4..2f4cc98fb6 100644 --- a/gtk/gtkscale.c +++ b/gtk/gtkscale.c @@ -1423,7 +1423,7 @@ marks_start_element (GMarkupParseContext *context, ; else if (strcmp (element_name, "mark") == 0) { - gdouble value; + gdouble value = 0; gboolean has_value = FALSE; GtkPositionType position = GTK_POS_BOTTOM; const gchar *msg_context = NULL; @@ -1578,7 +1578,6 @@ gtk_scale_buildable_custom_finished (GtkBuildable *buildable, { GtkScale *scale = GTK_SCALE (buildable); MarksSubparserData *marks_data; - GtkWidget *toplevel; if (strcmp (tagname, "marks") == 0) { diff --git a/gtk/gtksearchenginetracker.c b/gtk/gtksearchenginetracker.c index e3d5a3ae3c..62447f8c29 100644 --- a/gtk/gtksearchenginetracker.c +++ b/gtk/gtksearchenginetracker.c @@ -31,9 +31,15 @@ typedef struct _TrackerClient TrackerClient; +typedef enum +{ + TRACKER_0_6 = 1 << 0, + TRACKER_0_7 = 1 << 1 +} TrackerVersion; + typedef void (*TrackerArrayReply) (char **result, GError *error, gpointer user_data); -static TrackerClient * (*tracker_connect) (gboolean enable_warnings) = NULL; +static TrackerClient * (*tracker_connect) (gboolean enable_warnings, gint timeout) = NULL; static void (*tracker_disconnect) (TrackerClient *client) = NULL; static int (*tracker_get_version) (TrackerClient *client, GError **error) = NULL; static void (*tracker_cancel_last_call) (TrackerClient *client) = NULL; @@ -52,22 +58,24 @@ static struct TrackerDlMapping { const char *fn_name; gpointer *fn_ptr_ref; + TrackerVersion versions; } tracker_dl_mapping[] = { -#define MAP(a) { #a, (gpointer *)&a } - MAP (tracker_connect), - MAP (tracker_disconnect), - MAP (tracker_get_version), - MAP (tracker_cancel_last_call), - MAP (tracker_search_metadata_by_text_async), - MAP (tracker_search_metadata_by_text_and_location_async), +#define MAP(a,v) { #a, (gpointer *)&a, v } + MAP (tracker_connect, TRACKER_0_6 | TRACKER_0_7), + MAP (tracker_disconnect, TRACKER_0_6 | TRACKER_0_7), + MAP (tracker_get_version, TRACKER_0_6), + MAP (tracker_cancel_last_call, TRACKER_0_6 | TRACKER_0_7), + MAP (tracker_search_metadata_by_text_async, TRACKER_0_6 | TRACKER_0_7), + MAP (tracker_search_metadata_by_text_and_location_async, TRACKER_0_6 | TRACKER_0_7), #undef MAP }; -static void +static TrackerVersion open_libtracker (void) { static gboolean done = FALSE; + static TrackerVersion version = 0; if (!done) { @@ -78,16 +86,29 @@ open_libtracker (void) done = TRUE; flags = G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL; - tracker = g_module_open ("libtrackerclient.so.0", flags); + tracker = g_module_open ("libtracker-client-0.7.so.0", flags); + version = TRACKER_0_7; if (!tracker) - tracker = g_module_open ("libtracker.so.0", flags); + { + tracker = g_module_open ("libtrackerclient.so.0", flags); + version = TRACKER_0_6; + } if (!tracker) - return; + { + tracker = g_module_open ("libtracker.so.0", flags); + version = TRACKER_0_6; + } + + if (!tracker) + return 0; for (i = 0; i < G_N_ELEMENTS (tracker_dl_mapping); i++) { + if ((tracker_dl_mapping[i].versions & version) == 0) + continue; + if (!g_module_symbol (tracker, tracker_dl_mapping[i].fn_name, tracker_dl_mapping[i].fn_ptr_ref)) { @@ -98,10 +119,12 @@ open_libtracker (void) for (i = 0; i < G_N_ELEMENTS (tracker_dl_mapping); i++) tracker_dl_mapping[i].fn_ptr_ref = NULL; - return; + return 0; } } } + + return version; } struct _GtkSearchEngineTrackerPrivate @@ -109,6 +132,7 @@ struct _GtkSearchEngineTrackerPrivate GtkQuery *query; TrackerClient *client; gboolean query_pending; + TrackerVersion version; }; G_DEFINE_TYPE (GtkSearchEngineTracker, _gtk_search_engine_tracker, GTK_TYPE_SEARCH_ENGINE); @@ -161,7 +185,11 @@ search_callback (gchar **results, { gchar *uri; - uri = g_filename_to_uri (*results_p, NULL, NULL); + if (tracker->priv->version == TRACKER_0_6) + uri = g_filename_to_uri (*results_p, NULL, NULL); + else + uri = *results_p; + if (uri) hit_uris = g_list_prepend (hit_uris, uri); } @@ -170,7 +198,8 @@ search_callback (gchar **results, _gtk_search_engine_finished (GTK_SEARCH_ENGINE (tracker)); g_strfreev (results); - g_list_foreach (hit_uris, (GFunc)g_free, NULL); + if (tracker->priv->version == TRACKER_0_6) + g_list_foreach (hit_uris, (GFunc)g_free, NULL); g_list_free (hit_uris); } @@ -195,9 +224,14 @@ gtk_search_engine_tracker_start (GtkSearchEngine *engine) location = NULL; if (location_uri) { - location = g_filename_from_uri (location_uri, NULL, NULL); - g_free (location_uri); - } + if (tracker->priv->version == TRACKER_0_6) + { + location = g_filename_from_uri (location_uri, NULL, NULL); + g_free (location_uri); + } + else + location = location_uri; + } if (location) { @@ -287,34 +321,39 @@ _gtk_search_engine_tracker_new (void) { GtkSearchEngineTracker *engine; TrackerClient *tracker_client; + TrackerVersion version; GError *err = NULL; - open_libtracker (); + version = open_libtracker (); if (!tracker_connect) return NULL; - tracker_client = tracker_connect (FALSE); + tracker_client = tracker_connect (FALSE, -1); if (!tracker_client) return NULL; - if (!tracker_get_version) - return NULL; - - tracker_get_version (tracker_client, &err); - - if (err != NULL) + if (version == TRACKER_0_6) { - g_error_free (err); - tracker_disconnect (tracker_client); - return NULL; + if (!tracker_get_version) + return NULL; + + tracker_get_version (tracker_client, &err); + + if (err != NULL) + { + g_error_free (err); + tracker_disconnect (tracker_client); + return NULL; + } } engine = g_object_new (GTK_TYPE_SEARCH_ENGINE_TRACKER, NULL); engine->priv->client = tracker_client; engine->priv->query_pending = FALSE; + engine->priv->version = version; return GTK_SEARCH_ENGINE (engine); } diff --git a/gtk/gtksettings.c b/gtk/gtksettings.c index c3c1a78c3d..49172636ec 100644 --- a/gtk/gtksettings.c +++ b/gtk/gtksettings.c @@ -741,7 +741,7 @@ gtk_settings_class_init (GtkSettingsClass *class) * * A comma-separated list of print backends to use in the print * dialog. Available print backends depend on the GTK+ installation, - * and may include "pdf", "cups" or "lpr". + * and may include "file", "cups", "lpr" or "papi". * * Since: 2.10 */ diff --git a/gtk/gtksizegroup.c b/gtk/gtksizegroup.c index 5926b52557..6cd02c0e2e 100644 --- a/gtk/gtksizegroup.c +++ b/gtk/gtksizegroup.c @@ -223,6 +223,10 @@ queue_resize_on_widget (GtkWidget *widget, if (widget == parent) real_queue_resize (parent); } + else if (tmp_list->data == widget) + { + g_warning ("A container and its child are part of this SizeGroup"); + } else queue_resize_on_widget (tmp_list->data, FALSE); @@ -249,6 +253,10 @@ queue_resize_on_widget (GtkWidget *widget, if (widget == parent) real_queue_resize (parent); } + else if (tmp_list->data == widget) + { + g_warning ("A container and its child are part of this SizeGroup"); + } else queue_resize_on_widget (tmp_list->data, FALSE); diff --git a/gtk/gtksocket-x11.c b/gtk/gtksocket-x11.c index bbeb8af792..f6f3a3d489 100644 --- a/gtk/gtksocket-x11.c +++ b/gtk/gtksocket-x11.c @@ -70,9 +70,17 @@ _gtk_socket_windowing_realize_window (GtkSocket *socket) GDK_WINDOW_XWINDOW (window), &xattrs); + /* Sooooo, it turns out that mozilla, as per the gtk2xt code selects + for input on the socket with a mask of 0x0fffff (for god knows why) + which includes ButtonPressMask causing a BadAccess if someone else + also selects for this. As per the client-side windows merge we always + normally selects for button press so we can emulate it on client + side children that selects for button press. However, we don't need + this for GtkSocket, so we unselect it here, fixing the crashes in + firefox. */ XSelectInput (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XWINDOW (window), - xattrs.your_event_mask | + (xattrs.your_event_mask & ~ButtonPressMask) | SubstructureNotifyMask | SubstructureRedirectMask); } diff --git a/gtk/gtkstatusbar.c b/gtk/gtkstatusbar.c index 2bddfa88b6..0a494c912a 100644 --- a/gtk/gtkstatusbar.c +++ b/gtk/gtkstatusbar.c @@ -198,6 +198,8 @@ gtk_statusbar_init (GtkStatusbar *statusbar) box = GTK_BOX (statusbar); + gtk_widget_set_redraw_on_allocate (GTK_WIDGET (box), TRUE); + box->spacing = 2; box->homogeneous = FALSE; @@ -616,10 +618,10 @@ gtk_statusbar_create_window (GtkStatusbar *statusbar) GdkWindowAttr attributes; gint attributes_mask; GdkRectangle rect; - + g_return_if_fail (GTK_WIDGET_REALIZED (statusbar)); g_return_if_fail (statusbar->has_resize_grip); - + widget = GTK_WIDGET (statusbar); get_grip_rect (statusbar, &rect); @@ -640,6 +642,8 @@ gtk_statusbar_create_window (GtkStatusbar *statusbar) gdk_window_set_user_data (statusbar->grip_window, widget); + gdk_window_raise (statusbar->grip_window); + set_grip_cursor (statusbar); } @@ -858,10 +862,10 @@ gtk_statusbar_size_allocate (GtkWidget *widget, if (statusbar->has_resize_grip) { - get_grip_rect (statusbar, &rect); - + get_grip_rect (statusbar, &rect); + extra_children = has_extra_children (statusbar); - + /* If there are extra children, we don't want them to occupy * the space where we draw the resize grip, so we temporarily * shrink the allocation. @@ -882,14 +886,6 @@ gtk_statusbar_size_allocate (GtkWidget *widget, if (statusbar->has_resize_grip) { - if (statusbar->grip_window) - { - gdk_window_raise (statusbar->grip_window); - gdk_window_move_resize (statusbar->grip_window, - rect.x, rect.y, - rect.width, rect.height); - } - if (extra_children) { allocation->width += rect.width; @@ -913,12 +909,23 @@ gtk_statusbar_size_allocate (GtkWidget *widget, /* shrink the label to make room for the grip */ *allocation = child->allocation; allocation->width = MAX (1, allocation->width - rect.width); - if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) + if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) allocation->x += child->allocation.width - allocation->width; gtk_widget_size_allocate (child, allocation); } } + + if (statusbar->grip_window) + { + get_grip_rect (statusbar, &rect); + + gdk_window_raise (statusbar->grip_window); + gdk_window_move_resize (statusbar->grip_window, + rect.x, rect.y, + rect.width, rect.height); + } + } } diff --git a/gtk/gtkstatusicon.c b/gtk/gtkstatusicon.c index f7fa009010..1cdb0c15d3 100644 --- a/gtk/gtkstatusicon.c +++ b/gtk/gtkstatusicon.c @@ -370,6 +370,10 @@ gtk_status_icon_class_init (GtkStatusIconClass *class) * the default handler for the #GtkStatusIcon::query-tooltip signal * will take care of displaying the tooltip. * + * Note that some platforms have limitations on the length of tooltips + * that they allow on status icons, e.g. Windows only shows the first + * 64 characters. + * * Since: 2.16 */ g_object_class_install_property (gobject_class, @@ -2949,7 +2953,7 @@ gtk_status_icon_get_title (GtkStatusIcon *status_icon) { GtkStatusIconPrivate *priv; - g_return_if_fail (GTK_IS_STATUS_ICON (status_icon)); + g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), NULL); priv = status_icon->priv; diff --git a/gtk/gtktestutils.c b/gtk/gtktestutils.c index 383af9a7a1..64bf351976 100644 --- a/gtk/gtktestutils.c +++ b/gtk/gtktestutils.c @@ -21,6 +21,8 @@ /* need to get the prototypes of all get_type functions */ #define GTK_ENABLE_BROKEN #undef GTK_DISABLE_DEPRECATED +/* Need to get GDK_WINDOW_OBJECT */ +#undef GDK_DISABLE_DEPRECATED #include "config.h" diff --git a/gtk/gtktextbuffer.c b/gtk/gtktextbuffer.c index ceaa11344a..f82b6d875b 100644 --- a/gtk/gtktextbuffer.c +++ b/gtk/gtktextbuffer.c @@ -3807,11 +3807,7 @@ gtk_text_buffer_delete_selection (GtkTextBuffer *buffer, else { if (interactive) - { - gtk_text_buffer_begin_user_action (buffer); - gtk_text_buffer_delete_interactive (buffer, &start, &end, default_editable); - gtk_text_buffer_end_user_action (buffer); - } + gtk_text_buffer_delete_interactive (buffer, &start, &end, default_editable); else gtk_text_buffer_delete (buffer, &start, &end); @@ -3887,13 +3883,14 @@ gtk_text_buffer_backspace (GtkTextBuffer *buffer, if (gtk_text_buffer_delete_interactive (buffer, &start, &end, default_editable)) { - if (backspace_deletes_character) + /* special case \r\n, since we never want to reinsert \r */ + if (backspace_deletes_character && strcmp ("\r\n", cluster_text)) { gchar *normalized_text = g_utf8_normalize (cluster_text, strlen (cluster_text), G_NORMALIZE_NFD); glong len = g_utf8_strlen (normalized_text, -1); - + if (len > 1) gtk_text_buffer_insert_interactive (buffer, &start, diff --git a/gtk/gtktextlayout.c b/gtk/gtktextlayout.c index 319b8ce645..8c5d419b63 100644 --- a/gtk/gtktextlayout.c +++ b/gtk/gtktextlayout.c @@ -1812,56 +1812,59 @@ allocate_child_widgets (GtkTextLayout *text_layout, { PangoLayout *layout = display->layout; PangoLayoutIter *run_iter; - + run_iter = pango_layout_get_iter (layout); - do { PangoLayoutRun *run = pango_layout_iter_get_run_readonly (run_iter); - + if (run && is_shape (run)) { gint byte_index; GtkTextIter text_iter; - GtkTextChildAnchor *anchor = 0; - GList *widgets = 0; - - /* The pango iterator iterates in visual order. + GtkTextChildAnchor *anchor = NULL; + GList *widgets = NULL; + GList *l; + + /* The pango iterator iterates in visual order. * We use the byte index to find the child widget. */ - byte_index = pango_layout_iter_get_index (run_iter); line_display_index_to_iter (text_layout, display, &text_iter, byte_index, 0); anchor = gtk_text_iter_get_child_anchor (&text_iter); - widgets = gtk_text_child_anchor_get_widgets (anchor); - - if (widgets) + if (anchor) + widgets = gtk_text_child_anchor_get_widgets (anchor); + + for (l = widgets; l; l = l->next) { PangoRectangle extents; - GtkWidget *child = widgets->data; + GtkWidget *child = l->data; - /* We emit "allocate_child" with the x,y of - * the widget with respect to the top of the line - * and the left side of the buffer - */ - - pango_layout_iter_get_run_extents (run_iter, - NULL, - &extents); - - g_signal_emit (text_layout, - signals[ALLOCATE_CHILD], - 0, - child, - PANGO_PIXELS (extents.x) + display->x_offset, - PANGO_PIXELS (extents.y) + display->top_margin); - - g_list_free (widgets); + if (_gtk_anchored_child_get_layout (child) == text_layout) + { + + /* We emit "allocate_child" with the x,y of + * the widget with respect to the top of the line + * and the left side of the buffer + */ + pango_layout_iter_get_run_extents (run_iter, + NULL, + &extents); + + g_signal_emit (text_layout, + signals[ALLOCATE_CHILD], + 0, + child, + PANGO_PIXELS (extents.x) + display->x_offset, + PANGO_PIXELS (extents.y) + display->top_margin); + } } + + g_list_free (widgets); } } while (pango_layout_iter_next_run (run_iter)); - + pango_layout_iter_free (run_iter); } diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c index bf2d4b12b6..0c41e24c21 100644 --- a/gtk/gtktextview.c +++ b/gtk/gtktextview.c @@ -349,6 +349,7 @@ static GtkAdjustment* get_vadjustment (GtkTextView *text_view); static void gtk_text_view_do_popup (GtkTextView *text_view, GdkEventButton *event); +static void cancel_pending_scroll (GtkTextView *text_view); static void gtk_text_view_queue_scroll (GtkTextView *text_view, GtkTextMark *mark, gdouble within_margin, @@ -1412,16 +1413,21 @@ gtk_text_view_set_buffer (GtkTextView *text_view, g_signal_handlers_disconnect_by_func (text_view->buffer, gtk_text_view_paste_done_handler, text_view); - g_object_unref (text_view->buffer); - text_view->dnd_mark = NULL; - text_view->first_para_mark = NULL; if (GTK_WIDGET_REALIZED (text_view)) { GtkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (text_view), GDK_SELECTION_PRIMARY); gtk_text_buffer_remove_selection_clipboard (text_view->buffer, clipboard); - } + } + + if (text_view->layout) + gtk_text_layout_set_buffer (text_view->layout, NULL); + + g_object_unref (text_view->buffer); + text_view->dnd_mark = NULL; + text_view->first_para_mark = NULL; + cancel_pending_scroll (text_view); } text_view->buffer = buffer; @@ -2154,6 +2160,11 @@ gtk_text_view_scroll_to_mark (GtkTextView *text_view, g_return_if_fail (xalign >= 0.0 && xalign <= 1.0); g_return_if_fail (yalign >= 0.0 && yalign <= 1.0); + /* We need to verify that the buffer contains the mark, otherwise this + * can lead to data structure corruption later on. + */ + g_return_if_fail (get_buffer (text_view) == gtk_text_mark_get_buffer (mark)); + gtk_text_view_queue_scroll (text_view, mark, within_margin, use_align, @@ -2183,6 +2194,11 @@ gtk_text_view_scroll_mark_onscreen (GtkTextView *text_view, g_return_if_fail (GTK_IS_TEXT_VIEW (text_view)); g_return_if_fail (GTK_IS_TEXT_MARK (mark)); + /* We need to verify that the buffer contains the mark, otherwise this + * can lead to data structure corruption later on. + */ + g_return_if_fail (get_buffer (text_view) == gtk_text_mark_get_buffer (mark)); + gtk_text_view_scroll_to_mark (text_view, mark, 0.0, FALSE, 0.0, 0.0); } @@ -4314,7 +4330,8 @@ gtk_text_view_button_press_event (GtkWidget *widget, GdkEventButton *event) if (gtk_text_buffer_get_selection_bounds (get_buffer (text_view), &start, &end) && - gtk_text_iter_in_range (&iter, &start, &end)) + gtk_text_iter_in_range (&iter, &start, &end) && + !(event->state & GDK_SHIFT_MASK)) { text_view->drag_start_x = event->x; text_view->drag_start_y = event->y; @@ -7195,6 +7212,11 @@ gtk_text_view_value_changed (GtkAdjustment *adj, */ gtk_text_view_update_layout_width (text_view); + /* We also update the IM spot location here, since the IM context + * might do something that leads to validation. + */ + gtk_text_view_update_im_spot_location (text_view); + /* note that validation of onscreen could invoke this function * recursively, by scrolling to maintain first_para, or in response * to updating the layout width, however there is no problem with @@ -7229,6 +7251,9 @@ gtk_text_view_value_changed (GtkAdjustment *adj, text_view->first_validate_idle = 0; } + /* Finally we update the IM cursor location again, to ensure any + * changes made by the validation are pushed through. + */ gtk_text_view_update_im_spot_location (text_view); DV(g_print(">End scroll offset changed handler ("G_STRLOC")\n")); diff --git a/gtk/gtktoolitem.c b/gtk/gtktoolitem.c index 9c00b0dab2..7393f7e979 100644 --- a/gtk/gtktoolitem.c +++ b/gtk/gtktoolitem.c @@ -39,6 +39,22 @@ /** * SECTION:gtktoolitem * @short_description: The base class of widgets that can be added to GtkToolShell + * @see_also: + * + * #GtkToolbar + * The toolbar widget + * + * + * #GtkToolButton + * A subclass of #GtkToolItem that displays buttons on + * the toolbar + * + * + * #GtkSeparatorToolItem + * A subclass of #GtkToolItem that separates groups of + * items on a toolbar + * + * * * #GtkToolItems are widgets that can appear on a toolbar. To * create a toolbar item that contain something else than a button, use diff --git a/gtk/gtktooltip.c b/gtk/gtktooltip.c index 77e47772cd..66b29f1b77 100644 --- a/gtk/gtktooltip.c +++ b/gtk/gtktooltip.c @@ -84,7 +84,7 @@ struct _GtkTooltipClass static void gtk_tooltip_class_init (GtkTooltipClass *klass); static void gtk_tooltip_init (GtkTooltip *tooltip); -static void gtk_tooltip_finalize (GObject *object); +static void gtk_tooltip_dispose (GObject *object); static void gtk_tooltip_window_style_set (GtkTooltip *tooltip); static gboolean gtk_tooltip_paint_window (GtkTooltip *tooltip); @@ -106,7 +106,7 @@ gtk_tooltip_class_init (GtkTooltipClass *klass) object_class = G_OBJECT_CLASS (klass); - object_class->finalize = gtk_tooltip_finalize; + object_class->dispose = gtk_tooltip_dispose; } static void @@ -166,7 +166,7 @@ gtk_tooltip_init (GtkTooltip *tooltip) } static void -gtk_tooltip_finalize (GObject *object) +gtk_tooltip_dispose (GObject *object) { GtkTooltip *tooltip = GTK_TOOLTIP (object); @@ -194,9 +194,10 @@ gtk_tooltip_finalize (GObject *object) gtk_tooltip_display_closed, tooltip); gtk_widget_destroy (tooltip->window); + tooltip->window = NULL; } - G_OBJECT_CLASS (gtk_tooltip_parent_class)->finalize (object); + G_OBJECT_CLASS (gtk_tooltip_parent_class)->dispose (object); } /* public API */ @@ -767,6 +768,9 @@ static void gtk_tooltip_set_last_window (GtkTooltip *tooltip, GdkWindow *window) { + if (tooltip->last_window == window) + return; + if (tooltip->last_window) g_object_remove_weak_pointer (G_OBJECT (tooltip->last_window), (gpointer *) &tooltip->last_window); @@ -945,8 +949,6 @@ gtk_tooltip_show_tooltip (GdkDisplay *display) g_object_get (tooltip_widget, "has-tooltip", &has_tooltip, NULL); - g_assert (tooltip != NULL); - return_value = gtk_tooltip_run_requery (&tooltip_widget, tooltip, &x, &y); if (!return_value) return; @@ -1048,11 +1050,17 @@ tooltip_popup_timeout (gpointer data) GtkTooltip *tooltip; display = GDK_DISPLAY_OBJECT (data); + tooltip = g_object_get_data (G_OBJECT (display), + "gdk-display-current-tooltip"); + + /* This usually does not happen. However, it does occur in language + * bindings were reference counting of objects behaves differently. + */ + if (!tooltip) + return FALSE; gtk_tooltip_show_tooltip (display); - tooltip = g_object_get_data (G_OBJECT (display), - "gdk-display-current-tooltip"); tooltip->timeout_id = 0; return FALSE; @@ -1068,7 +1076,7 @@ gtk_tooltip_start_delay (GdkDisplay *display) tooltip = g_object_get_data (G_OBJECT (display), "gdk-display-current-tooltip"); - if (tooltip && GTK_TOOLTIP_VISIBLE (tooltip)) + if (!tooltip || GTK_TOOLTIP_VISIBLE (tooltip)) return; if (tooltip->timeout_id) diff --git a/gtk/gtktrayicon-x11.c b/gtk/gtktrayicon-x11.c index 075ff69709..32c3140545 100644 --- a/gtk/gtktrayicon-x11.c +++ b/gtk/gtktrayicon-x11.c @@ -441,7 +441,7 @@ gtk_tray_icon_send_manager_message (GtkTrayIcon *icon, gdk_error_trap_push (); XSendEvent (display, icon->priv->manager_window, False, NoEventMask, (XEvent *)&ev); - XSync (display, False); + gdk_display_sync (gtk_widget_get_display (GTK_WIDGET (icon))); gdk_error_trap_pop (); } @@ -646,11 +646,12 @@ _gtk_tray_icon_send_message (GtkTrayIcon *icon, gint len) { guint stamp; - + Display *xdisplay; + g_return_val_if_fail (GTK_IS_TRAY_ICON (icon), 0); g_return_val_if_fail (timeout >= 0, 0); g_return_val_if_fail (message != NULL, 0); - + if (icon->priv->manager_window == None) return 0; @@ -665,14 +666,12 @@ _gtk_tray_icon_send_message (GtkTrayIcon *icon, timeout, len, stamp); /* Now to send the actual message */ + xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon))); gdk_error_trap_push (); while (len > 0) { XClientMessageEvent ev; - Display *xdisplay; - xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon))); - memset (&ev, 0, sizeof (ev)); ev.type = ClientMessage; ev.window = (Window)gtk_plug_get_id (GTK_PLUG (icon)); @@ -692,11 +691,10 @@ _gtk_tray_icon_send_message (GtkTrayIcon *icon, } XSendEvent (xdisplay, - icon->priv->manager_window, False, + icon->priv->manager_window, False, StructureNotifyMask, (XEvent *)&ev); - XSync (xdisplay, False); } - + gdk_display_sync (gtk_widget_get_display (GTK_WIDGET (icon))); gdk_error_trap_pop (); return stamp; diff --git a/gtk/gtktreemodelfilter.c b/gtk/gtktreemodelfilter.c index cc5b86ebba..074a7a4fa1 100644 --- a/gtk/gtktreemodelfilter.c +++ b/gtk/gtktreemodelfilter.c @@ -73,7 +73,7 @@ struct _FilterLevel gint ref_count; gint visible_nodes; - FilterElt *parent_elt; + gint parent_elt_index; FilterLevel *parent_level; }; @@ -129,6 +129,9 @@ enum #define FILTER_ELT(filter_elt) ((FilterElt *)filter_elt) #define FILTER_LEVEL(filter_level) ((FilterLevel *)filter_level) +#define FILTER_LEVEL_PARENT_ELT(level) (&g_array_index (FILTER_LEVEL ((level))->parent_level->array, FilterElt, FILTER_LEVEL ((level))->parent_elt_index)) +#define FILTER_LEVEL_ELT_INDEX(level, elt) (FILTER_ELT ((elt)) - FILTER_ELT (FILTER_LEVEL ((level))->array->data)) + /* general code (object/interface init, properties, etc) */ static void gtk_tree_model_filter_tree_model_init (GtkTreeModelIface *iface); static void gtk_tree_model_filter_drag_source_init (GtkTreeDragSourceIface *iface); @@ -214,7 +217,7 @@ static gboolean gtk_tree_model_filter_drag_data_delete (GtkTr /* private functions */ static void gtk_tree_model_filter_build_level (GtkTreeModelFilter *filter, FilterLevel *parent_level, - FilterElt *parent_elt, + gint parent_elt_index, gboolean emit_inserted); static void gtk_tree_model_filter_free_level (GtkTreeModelFilter *filter, @@ -257,6 +260,8 @@ static GtkTreePath *gtk_real_tree_model_filter_convert_child_path_to_path (GtkTr static FilterElt *gtk_tree_model_filter_get_nth (GtkTreeModelFilter *filter, FilterLevel *level, int n); +static gboolean gtk_tree_model_filter_elt_is_visible_in_target (FilterLevel *level, + FilterElt *elt); static FilterElt *gtk_tree_model_filter_get_nth_visible (GtkTreeModelFilter *filter, FilterLevel *level, int n); @@ -436,12 +441,13 @@ gtk_tree_model_filter_get_property (GObject *object, static void gtk_tree_model_filter_build_level (GtkTreeModelFilter *filter, FilterLevel *parent_level, - FilterElt *parent_elt, + gint parent_elt_index, gboolean emit_inserted) { GtkTreeIter iter; GtkTreeIter first_node; GtkTreeIter root; + FilterElt *parent_elt = NULL; FilterLevel *new_level; gint length = 0; gint i; @@ -474,6 +480,8 @@ gtk_tree_model_filter_build_level (GtkTreeModelFilter *filter, GtkTreeIter parent_iter; GtkTreeIter child_parent_iter; + parent_elt = &g_array_index (parent_level->array, FilterElt, parent_elt_index); + parent_iter.stamp = filter->priv->stamp; parent_iter.user_data = parent_level; parent_iter.user_data2 = parent_elt; @@ -499,10 +507,10 @@ gtk_tree_model_filter_build_level (GtkTreeModelFilter *filter, length); new_level->ref_count = 0; new_level->visible_nodes = 0; - new_level->parent_elt = parent_elt; + new_level->parent_elt_index = parent_elt_index; new_level->parent_level = parent_level; - if (parent_elt) + if (parent_elt_index >= 0) parent_elt->children = new_level; else filter->priv->root = new_level; @@ -510,9 +518,9 @@ gtk_tree_model_filter_build_level (GtkTreeModelFilter *filter, /* increase the count of zero ref_counts */ while (parent_level) { - parent_elt->zero_ref_count++; + g_array_index (parent_level->array, FilterElt, parent_elt_index).zero_ref_count++; - parent_elt = parent_level->parent_elt; + parent_elt_index = parent_level->parent_elt_index; parent_level = parent_level->parent_level; } if (new_level != filter->priv->root) @@ -526,6 +534,7 @@ gtk_tree_model_filter_build_level (GtkTreeModelFilter *filter, { if (gtk_tree_model_filter_visible (filter, &iter)) { + GtkTreeIter f_iter; FilterElt filter_elt; filter_elt.offset = i; @@ -540,26 +549,29 @@ gtk_tree_model_filter_build_level (GtkTreeModelFilter *filter, g_array_append_val (new_level->array, filter_elt); new_level->visible_nodes++; + f_iter.stamp = filter->priv->stamp; + f_iter.user_data = new_level; + f_iter.user_data2 = &(g_array_index (new_level->array, FilterElt, new_level->array->len - 1)); + if (new_level->parent_level || filter->priv->virtual_root) + gtk_tree_model_filter_ref_node (GTK_TREE_MODEL (filter), &f_iter); + + if (emit_inserted) { - GtkTreeIter f_iter; + GtkTreePath *f_path; + GtkTreeIter children; - f_iter.stamp = filter->priv->stamp; - f_iter.user_data = new_level; - f_iter.user_data2 = &(g_array_index (new_level->array, FilterElt, new_level->array->len - 1)); + f_path = gtk_tree_model_get_path (GTK_TREE_MODEL (filter), + &f_iter); + gtk_tree_model_row_inserted (GTK_TREE_MODEL (filter), + f_path, &f_iter); + gtk_tree_path_free (f_path); - gtk_tree_model_filter_ref_node (GTK_TREE_MODEL (filter), &f_iter); - - if (emit_inserted) - { - GtkTreePath *f_path; - - f_path = gtk_tree_model_get_path (GTK_TREE_MODEL (filter), - &f_iter); - gtk_tree_model_row_inserted (GTK_TREE_MODEL (filter), - f_path, &f_iter); - gtk_tree_path_free (f_path); - } + if (gtk_tree_model_iter_children (filter->priv->child_model, + &children, &iter)) + gtk_tree_model_filter_update_children (filter, + new_level, + FILTER_ELT (f_iter.user_data2)); } } i++; @@ -626,13 +638,13 @@ gtk_tree_model_filter_free_level (GtkTreeModelFilter *filter, if (filter_level->ref_count == 0) { FilterLevel *parent_level = filter_level->parent_level; - FilterElt *parent_elt = filter_level->parent_elt; + gint parent_elt_index = filter_level->parent_elt_index; while (parent_level) { - parent_elt->zero_ref_count--; + g_array_index (parent_level->array, FilterElt, parent_elt_index).zero_ref_count--; - parent_elt = parent_level->parent_elt; + parent_elt_index = parent_level->parent_elt_index; parent_level = parent_level->parent_level; } @@ -640,8 +652,8 @@ gtk_tree_model_filter_free_level (GtkTreeModelFilter *filter, filter->priv->zero_ref_count--; } - if (filter_level->parent_elt) - filter_level->parent_elt->children = NULL; + if (filter_level->parent_elt_index >= 0) + FILTER_LEVEL_PARENT_ELT (filter_level)->children = NULL; else filter->priv->root = NULL; @@ -672,7 +684,10 @@ gtk_tree_model_filter_elt_get_path (FilterLevel *level, { gtk_tree_path_prepend_index (path, walker2->offset); - walker2 = walker->parent_elt; + if (!walker->parent_level) + break; + + walker2 = FILTER_LEVEL_PARENT_ELT (walker); walker = walker->parent_level; } @@ -804,6 +819,32 @@ gtk_tree_model_filter_get_nth (GtkTreeModelFilter *filter, return &g_array_index (level->array, FilterElt, n); } +static gboolean +gtk_tree_model_filter_elt_is_visible_in_target (FilterLevel *level, + FilterElt *elt) +{ + gint elt_index; + + if (!elt->visible) + return FALSE; + + if (level->parent_elt_index == -1) + return TRUE; + + do + { + elt_index = level->parent_elt_index; + level = level->parent_level; + + if (elt_index >= 0 + && !g_array_index (level->array, FilterElt, elt_index).visible) + return FALSE; + } + while (level); + + return TRUE; +} + static FilterElt * gtk_tree_model_filter_get_nth_visible (GtkTreeModelFilter *filter, FilterLevel *level, @@ -848,11 +889,11 @@ gtk_tree_model_filter_fetch_child (GtkTreeModelFilter *filter, FilterElt elt; /* check if child exists and is visible */ - if (level->parent_elt) + if (level->parent_elt_index >= 0) { c_parent_path = gtk_tree_model_filter_elt_get_path (level->parent_level, - level->parent_elt, + FILTER_LEVEL_PARENT_ELT (level), filter->priv->virtual_root); if (!c_parent_path) return NULL; @@ -931,7 +972,7 @@ gtk_tree_model_filter_fetch_child (GtkTreeModelFilter *filter, { FilterElt *e = &(g_array_index (level->array, FilterElt, i)); if (e->children) - e->children->parent_elt = e; + e->children->parent_elt_index = i; } c_iter.stamp = filter->priv->stamp; @@ -950,14 +991,18 @@ gtk_tree_model_filter_remove_node (GtkTreeModelFilter *filter, { FilterElt *elt, *parent; FilterLevel *level, *parent_level; - gint i, length; + gint i, length, parent_elt_index; gboolean emit_child_toggled = FALSE; level = FILTER_LEVEL (iter->user_data); elt = FILTER_ELT (iter->user_data2); - parent = level->parent_elt; + parent_elt_index = level->parent_elt_index; + if (parent_elt_index >= 0) + parent = FILTER_LEVEL_PARENT_ELT (level); + else + parent = NULL; parent_level = level->parent_level; length = level->array->len; @@ -972,7 +1017,10 @@ gtk_tree_model_filter_remove_node (GtkTreeModelFilter *filter, * if level != root level and visible nodes == 0, emit row-has-child-toggled. */ - if (level != filter->priv->root && level->visible_nodes == 0) + if (level != filter->priv->root + && level->visible_nodes == 0 + && parent + && parent->visible) emit_child_toggled = TRUE; if (length > 1) @@ -980,9 +1028,13 @@ gtk_tree_model_filter_remove_node (GtkTreeModelFilter *filter, GtkTreePath *path; FilterElt *tmp; - /* we emit row-deleted, and remove the node from the cache. + /* We emit row-deleted, and remove the node from the cache. + * If it has any children, these will be removed here as well. */ + if (elt->children) + gtk_tree_model_filter_free_level (filter, elt->children); + path = gtk_tree_model_get_path (GTK_TREE_MODEL (filter), iter); elt->visible = FALSE; gtk_tree_model_filter_increment_stamp (filter); @@ -1015,7 +1067,7 @@ gtk_tree_model_filter_remove_node (GtkTreeModelFilter *filter, */ elt = &g_array_index (level->array, FilterElt, i); if (elt->children) - elt->children->parent_elt = elt; + elt->children->parent_elt_index = i; } } } @@ -1024,10 +1076,16 @@ gtk_tree_model_filter_remove_node (GtkTreeModelFilter *filter, { GtkTreePath *path; - /* we emit row-deleted, but keep the node in the cache and - * referenced. + /* We emit row-deleted, but keep the node in the cache and + * referenced. Its children will be removed. */ + if (elt->children) + { + gtk_tree_model_filter_free_level (filter, elt->children); + elt->children = NULL; + } + path = gtk_tree_model_get_path (GTK_TREE_MODEL (filter), iter); elt->visible = FALSE; gtk_tree_model_filter_increment_stamp (filter); @@ -1038,7 +1096,7 @@ gtk_tree_model_filter_remove_node (GtkTreeModelFilter *filter, { GtkTreePath *path; - /* blow level away */ + /* Blow level away, including any child levels */ path = gtk_tree_model_get_path (GTK_TREE_MODEL (filter), iter); elt->visible = FALSE; @@ -1170,6 +1228,7 @@ gtk_tree_model_filter_row_changed (GtkTreeModel *c_model, gboolean requested_state; gboolean current_state; gboolean free_c_path = FALSE; + gboolean signals_emitted = FALSE; g_return_if_fail (c_path != NULL || c_iter != NULL); @@ -1230,14 +1289,18 @@ gtk_tree_model_filter_row_changed (GtkTreeModel *c_model, */ gtk_tree_path_free (path); path = gtk_tree_model_get_path (GTK_TREE_MODEL (filter), &iter); - gtk_tree_model_row_changed (GTK_TREE_MODEL (filter), path, &iter); level = FILTER_LEVEL (iter.user_data); elt = FILTER_ELT (iter.user_data2); - /* and update the children */ - if (gtk_tree_model_iter_children (c_model, &children, &real_c_iter)) - gtk_tree_model_filter_update_children (filter, level, elt); + if (gtk_tree_model_filter_elt_is_visible_in_target (level, elt)) + { + gtk_tree_model_row_changed (GTK_TREE_MODEL (filter), path, &iter); + + /* and update the children */ + if (gtk_tree_model_iter_children (c_model, &children, &real_c_iter)) + gtk_tree_model_filter_update_children (filter, level, elt); + } goto done; } @@ -1250,27 +1313,29 @@ gtk_tree_model_filter_row_changed (GtkTreeModel *c_model, /* make sure the new item has been pulled in */ if (!filter->priv->root) { - gint i; FilterLevel *root; - gtk_tree_model_filter_build_level (filter, NULL, NULL, FALSE); + gtk_tree_model_filter_build_level (filter, NULL, -1, TRUE); + + /* We will only proceed below if the item is found. If the item + * is found, we can be sure row-inserted has just been emitted + * for it. + */ + signals_emitted = TRUE; root = FILTER_LEVEL (filter->priv->root); - - if (root) - { - for (i = 0; i < root->array->len; i++) - g_array_index (root->array, FilterElt, i).visible = FALSE; - root->visible_nodes = 0; - } } gtk_tree_model_filter_increment_stamp (filter); + /* We need to allow to build new levels, because we are then pulling + * in a child in an invisible level. We only want to find path if it + * is in a visible level (and thus has a parent that is visible). + */ if (!path) path = gtk_real_tree_model_filter_convert_child_path_to_path (filter, c_path, - TRUE, + FALSE, TRUE); if (!path) @@ -1289,15 +1354,32 @@ gtk_tree_model_filter_row_changed (GtkTreeModel *c_model, level->visible_nodes++; } - if ((level->parent_elt && level->parent_elt->visible) || !level->parent_elt) + if (gtk_tree_model_filter_elt_is_visible_in_target (level, elt)) { /* visibility changed -- reget path */ gtk_tree_path_free (path); path = gtk_tree_model_get_path (GTK_TREE_MODEL (filter), &iter); - gtk_tree_model_row_inserted (GTK_TREE_MODEL (filter), path, &iter); + if (!signals_emitted) + gtk_tree_model_row_inserted (GTK_TREE_MODEL (filter), path, &iter); - if (gtk_tree_model_iter_children (c_model, &children, c_iter)) + if (level->parent_level && level->visible_nodes == 1) + { + /* We know that this is the first visible node in this level, so + * we need to emit row-has-child-toggled on the parent. This + * does not apply to the root level. + */ + + gtk_tree_path_up (path); + gtk_tree_model_get_iter (GTK_TREE_MODEL (filter), &iter, path); + + gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (filter), + path, + &iter); + } + + if (!signals_emitted + && gtk_tree_model_iter_children (c_model, &children, c_iter)) gtk_tree_model_filter_update_children (filter, level, elt); } @@ -1379,7 +1461,7 @@ gtk_tree_model_filter_row_inserted (GtkTreeModel *c_model, goto done; /* build level will pull in the new child */ - gtk_tree_model_filter_build_level (filter, NULL, NULL, FALSE); + gtk_tree_model_filter_build_level (filter, NULL, -1, FALSE); if (filter->priv->root && FILTER_LEVEL (filter->priv->root)->visible_nodes) @@ -1506,7 +1588,7 @@ gtk_tree_model_filter_row_inserted (GtkTreeModel *c_model, { FilterElt *e = &g_array_index (level->array, FilterElt, i); if (e->children) - e->children->parent_elt = e; + e->children->parent_elt_index = i; } /* don't emit the signal if we aren't visible */ @@ -1555,6 +1637,7 @@ gtk_tree_model_filter_row_has_child_toggled (GtkTreeModel *c_model, GtkTreeIter iter; FilterLevel *level; FilterElt *elt; + gboolean requested_state; g_return_if_fail (c_path != NULL && c_iter != NULL); @@ -1564,12 +1647,13 @@ gtk_tree_model_filter_row_has_child_toggled (GtkTreeModel *c_model, if (filter->priv->virtual_root && !filter->priv->root && !gtk_tree_path_compare (c_path, filter->priv->virtual_root)) { - gtk_tree_model_filter_build_level (filter, NULL, NULL, TRUE); + gtk_tree_model_filter_build_level (filter, NULL, -1, TRUE); return; } - if (!gtk_tree_model_filter_visible (filter, c_iter)) - return; + /* For all other levels, there is a chance that the visibility state + * of the parent has changed now. + */ path = gtk_real_tree_model_filter_convert_child_path_to_path (filter, c_path, @@ -1580,18 +1664,60 @@ gtk_tree_model_filter_row_has_child_toggled (GtkTreeModel *c_model, gtk_tree_model_filter_get_iter_full (GTK_TREE_MODEL (data), &iter, path); - gtk_tree_path_free (path); - level = FILTER_LEVEL (iter.user_data); elt = FILTER_ELT (iter.user_data2); - g_assert (elt->visible); + gtk_tree_path_free (path); + + requested_state = gtk_tree_model_filter_visible (filter, c_iter); + + if (!elt->visible && !requested_state) + { + /* The parent node currently is not visible and will not become + * visible, so we will not pass on the row-has-child-toggled event. + */ + return; + } + else if (elt->visible && !requested_state) + { + /* The node is no longer visible, so it has to be removed. + * _remove_node() takes care of emitting row-has-child-toggled + * when required. + */ + level->visible_nodes--; + + gtk_tree_model_filter_remove_node (filter, &iter); + + return; + } + else if (!elt->visible && requested_state) + { + elt->visible = TRUE; + level->visible_nodes++; + + /* Only insert if the parent is visible in the target */ + if (gtk_tree_model_filter_elt_is_visible_in_target (level, elt)) + { + path = gtk_tree_model_get_path (GTK_TREE_MODEL (filter), &iter); + gtk_tree_model_row_inserted (GTK_TREE_MODEL (filter), path, &iter); + gtk_tree_path_free (path); + + /* We do not update children now, because that will happen + * below. + */ + } + } + /* For the remaining possibility, elt->visible && requested_state + * no action is required. + */ /* If this node is referenced and has children, build the level so we * can monitor it for changes. */ if (elt->ref_count > 1 && gtk_tree_model_iter_has_child (c_model, c_iter)) - gtk_tree_model_filter_build_level (filter, level, elt, TRUE); + gtk_tree_model_filter_build_level (filter, level, + FILTER_LEVEL_ELT_INDEX (level, elt), + TRUE); /* get a path taking only visible nodes into account */ path = gtk_tree_model_get_path (GTK_TREE_MODEL (data), &iter); @@ -1607,11 +1733,12 @@ gtk_tree_model_filter_row_deleted (GtkTreeModel *c_model, GtkTreeModelFilter *filter = GTK_TREE_MODEL_FILTER (data); GtkTreePath *path; GtkTreeIter iter; - FilterElt *elt, *parent = NULL; + FilterElt *elt; FilterLevel *level, *parent_level = NULL; gboolean emit_child_toggled = FALSE; gint offset; gint i; + gint parent_elt_index = -1; g_return_if_fail (c_path != NULL); @@ -1749,7 +1876,7 @@ gtk_tree_model_filter_row_deleted (GtkTreeModel *c_model, if (elt->offset > offset) elt->offset--; if (elt->children) - elt->children->parent_elt = elt; + elt->children->parent_elt_index = i; } return; @@ -1774,7 +1901,7 @@ gtk_tree_model_filter_row_deleted (GtkTreeModel *c_model, { emit_child_toggled = TRUE; parent_level = level->parent_level; - parent = level->parent_elt; + parent_elt_index = level->parent_elt_index; } /* emit row_deleted */ @@ -1819,7 +1946,7 @@ gtk_tree_model_filter_row_deleted (GtkTreeModel *c_model, if (elt->offset > offset) elt->offset--; if (elt->children) - elt->children->parent_elt = elt; + elt->children->parent_elt_index = i; } } @@ -1830,7 +1957,7 @@ gtk_tree_model_filter_row_deleted (GtkTreeModel *c_model, iter.stamp = filter->priv->stamp; iter.user_data = parent_level; - iter.user_data2 = parent; + iter.user_data2 = &g_array_index (parent_level->array, FilterElt, parent_elt_index); /* We set in_row_deleted to TRUE to avoid a level build triggered * by row-has-child-toggled (parent model could call iter_has_child @@ -2013,7 +2140,7 @@ gtk_tree_model_filter_rows_reordered (GtkTreeModel *c_model, { FilterElt *e = &g_array_index (level->array, FilterElt, i); if (e->children) - e->children->parent_elt = e; + e->children->parent_elt_index = i; } /* emit rows_reordered */ @@ -2114,7 +2241,7 @@ gtk_tree_model_filter_get_iter_full (GtkTreeModel *model, indices = gtk_tree_path_get_indices (path); if (filter->priv->root == NULL) - gtk_tree_model_filter_build_level (filter, NULL, NULL, FALSE); + gtk_tree_model_filter_build_level (filter, NULL, -1, FALSE); level = FILTER_LEVEL (filter->priv->root); depth = gtk_tree_path_get_depth (path); @@ -2134,7 +2261,9 @@ gtk_tree_model_filter_get_iter_full (GtkTreeModel *model, elt = gtk_tree_model_filter_get_nth (filter, level, indices[i]); if (!elt->children) - gtk_tree_model_filter_build_level (filter, level, elt, FALSE); + gtk_tree_model_filter_build_level (filter, level, + FILTER_LEVEL_ELT_INDEX (level, elt), + FALSE); level = elt->children; } @@ -2169,7 +2298,7 @@ gtk_tree_model_filter_get_iter (GtkTreeModel *model, indices = gtk_tree_path_get_indices (path); if (filter->priv->root == NULL) - gtk_tree_model_filter_build_level (filter, NULL, NULL, FALSE); + gtk_tree_model_filter_build_level (filter, NULL, -1, FALSE); level = FILTER_LEVEL (filter->priv->root); depth = gtk_tree_path_get_depth (path); @@ -2189,7 +2318,9 @@ gtk_tree_model_filter_get_iter (GtkTreeModel *model, elt = gtk_tree_model_filter_get_nth_visible (filter, level, indices[i]); if (!elt->children) - gtk_tree_model_filter_build_level (filter, level, elt, FALSE); + gtk_tree_model_filter_build_level (filter, level, + FILTER_LEVEL_ELT_INDEX (level, elt), + FALSE); level = elt->children; } @@ -2216,6 +2347,7 @@ gtk_tree_model_filter_get_path (GtkTreeModel *model, GtkTreePath *retval; FilterLevel *level; FilterElt *elt; + gint elt_index; g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (model), NULL); g_return_val_if_fail (GTK_TREE_MODEL_FILTER (model)->priv->child_model != NULL, NULL); @@ -2223,6 +2355,7 @@ gtk_tree_model_filter_get_path (GtkTreeModel *model, level = iter->user_data; elt = iter->user_data2; + elt_index = FILTER_LEVEL_ELT_INDEX (level, elt); if (!elt->visible) return NULL; @@ -2233,7 +2366,7 @@ gtk_tree_model_filter_get_path (GtkTreeModel *model, { int i = 0, index = 0; - while (&g_array_index (level->array, FilterElt, i) != elt) + while (i < elt_index) { if (g_array_index (level->array, FilterElt, i).visible) index++; @@ -2243,7 +2376,7 @@ gtk_tree_model_filter_get_path (GtkTreeModel *model, } gtk_tree_path_prepend_index (retval, index); - elt = level->parent_elt; + elt_index = level->parent_elt_index; level = level->parent_level; } @@ -2336,7 +2469,7 @@ gtk_tree_model_filter_iter_children (GtkTreeModel *model, int i = 0; if (!filter->priv->root) - gtk_tree_model_filter_build_level (filter, NULL, NULL, FALSE); + gtk_tree_model_filter_build_level (filter, NULL, -1, FALSE); if (!filter->priv->root) return FALSE; @@ -2366,20 +2499,24 @@ gtk_tree_model_filter_iter_children (GtkTreeModel *model, else { int i = 0; + FilterElt *elt; - if (FILTER_ELT (parent->user_data2)->children == NULL) + elt = FILTER_ELT (parent->user_data2); + + if (elt->children == NULL) gtk_tree_model_filter_build_level (filter, FILTER_LEVEL (parent->user_data), - FILTER_ELT (parent->user_data2), + FILTER_LEVEL_ELT_INDEX (parent->user_data, elt), FALSE); - if (FILTER_ELT (parent->user_data2)->children == NULL) + + if (elt->children == NULL) return FALSE; - if (FILTER_ELT (parent->user_data2)->children->visible_nodes <= 0) + if (elt->children->visible_nodes <= 0) return FALSE; iter->stamp = filter->priv->stamp; - iter->user_data = FILTER_ELT (parent->user_data2)->children; + iter->user_data = elt->children; level = FILTER_LEVEL (iter->user_data); @@ -2429,7 +2566,8 @@ gtk_tree_model_filter_iter_has_child (GtkTreeModel *model, if (!elt->children && gtk_tree_model_iter_has_child (filter->priv->child_model, &child_iter)) gtk_tree_model_filter_build_level (filter, FILTER_LEVEL (iter->user_data), - elt, FALSE); + FILTER_LEVEL_ELT_INDEX (iter->user_data, elt), + FALSE); if (elt->children && elt->children->visible_nodes > 0) return TRUE; @@ -2453,7 +2591,7 @@ gtk_tree_model_filter_iter_n_children (GtkTreeModel *model, if (!iter) { if (!filter->priv->root) - gtk_tree_model_filter_build_level (filter, NULL, NULL, FALSE); + gtk_tree_model_filter_build_level (filter, NULL, -1, FALSE); if (filter->priv->root) return FILTER_LEVEL (filter->priv->root)->visible_nodes; @@ -2472,7 +2610,8 @@ gtk_tree_model_filter_iter_n_children (GtkTreeModel *model, gtk_tree_model_iter_has_child (filter->priv->child_model, &child_iter)) gtk_tree_model_filter_build_level (filter, FILTER_LEVEL (iter->user_data), - elt, FALSE); + FILTER_LEVEL_ELT_INDEX (iter->user_data, elt), + FALSE); if (elt->children) return elt->children->visible_nodes; @@ -2538,7 +2677,7 @@ gtk_tree_model_filter_iter_parent (GtkTreeModel *model, { iter->stamp = GTK_TREE_MODEL_FILTER (model)->priv->stamp; iter->user_data = level->parent_level; - iter->user_data2 = level->parent_elt; + iter->user_data2 = FILTER_LEVEL_PARENT_ELT (level); return TRUE; } @@ -2571,14 +2710,14 @@ gtk_tree_model_filter_ref_node (GtkTreeModel *model, if (level->ref_count == 1) { FilterLevel *parent_level = level->parent_level; - FilterElt *parent_elt = level->parent_elt; + gint parent_elt_index = level->parent_elt_index; /* we were at zero -- time to decrease the zero_ref_count val */ while (parent_level) { - parent_elt->zero_ref_count--; + g_array_index (parent_level->array, FilterElt, parent_elt_index).zero_ref_count--; - parent_elt = parent_level->parent_elt; + parent_elt_index = parent_level->parent_elt_index; parent_level = parent_level->parent_level; } @@ -2624,14 +2763,14 @@ gtk_tree_model_filter_real_unref_node (GtkTreeModel *model, if (level->ref_count == 0) { FilterLevel *parent_level = level->parent_level; - FilterElt *parent_elt = level->parent_elt; + gint parent_elt_index = level->parent_elt_index; /* we are at zero -- time to increase the zero_ref_count val */ while (parent_level) { - parent_elt->zero_ref_count++; + g_array_index (parent_level->array, FilterElt, parent_elt_index).zero_ref_count++; - parent_elt = parent_level->parent_elt; + parent_elt_index = parent_level->parent_elt_index; parent_level = parent_level->parent_level; } @@ -3037,6 +3176,7 @@ gtk_tree_model_filter_convert_child_iter_to_iter (GtkTreeModelFilter *filter, g_return_val_if_fail (filter->priv->child_model != NULL, FALSE); g_return_val_if_fail (filter_iter != NULL, FALSE); g_return_val_if_fail (child_iter != NULL, FALSE); + g_return_val_if_fail (filter_iter != child_iter, FALSE); filter_iter->stamp = 0; @@ -3076,6 +3216,7 @@ gtk_tree_model_filter_convert_iter_to_child_iter (GtkTreeModelFilter *filter, g_return_if_fail (child_iter != NULL); g_return_if_fail (filter_iter != NULL); g_return_if_fail (filter_iter->stamp == filter->priv->stamp); + g_return_if_fail (filter_iter != child_iter); if (GTK_TREE_MODEL_FILTER_CACHE_CHILD_ITERS (filter)) { @@ -3124,7 +3265,7 @@ gtk_real_tree_model_filter_convert_child_path_to_path (GtkTreeModelFilter *filte child_indices = gtk_tree_path_get_indices (real_path); if (filter->priv->root == NULL && build_levels) - gtk_tree_model_filter_build_level (filter, NULL, NULL, FALSE); + gtk_tree_model_filter_build_level (filter, NULL, -1, FALSE); level = FILTER_LEVEL (filter->priv->root); for (i = 0; i < gtk_tree_path_get_depth (real_path); i++) @@ -3144,7 +3285,9 @@ gtk_real_tree_model_filter_convert_child_path_to_path (GtkTreeModelFilter *filte { gtk_tree_path_append_index (retval, j); if (!tmp->children && build_levels) - gtk_tree_model_filter_build_level (filter, level, tmp, FALSE); + gtk_tree_model_filter_build_level (filter, level, + FILTER_LEVEL_ELT_INDEX (level, tmp), + FALSE); level = tmp->children; found_child = TRUE; } @@ -3166,7 +3309,9 @@ gtk_real_tree_model_filter_convert_child_path_to_path (GtkTreeModelFilter *filte gtk_tree_path_append_index (retval, j); if (!tmp->children && build_levels) - gtk_tree_model_filter_build_level (filter, level, tmp, FALSE); + gtk_tree_model_filter_build_level (filter, level, + FILTER_LEVEL_ELT_INDEX (level, tmp), + FALSE); level = tmp->children; found_child = TRUE; } @@ -3258,7 +3403,7 @@ gtk_tree_model_filter_convert_path_to_child_path (GtkTreeModelFilter *filter, retval = gtk_tree_path_new (); filter_indices = gtk_tree_path_get_indices (filter_path); if (!filter->priv->root) - gtk_tree_model_filter_build_level (filter, NULL, NULL, FALSE); + gtk_tree_model_filter_build_level (filter, NULL, -1, FALSE); level = FILTER_LEVEL (filter->priv->root); for (i = 0; i < gtk_tree_path_get_depth (filter_path); i++) @@ -3275,7 +3420,9 @@ gtk_tree_model_filter_convert_path_to_child_path (GtkTreeModelFilter *filter, filter_indices[i]); if (elt->children == NULL) - gtk_tree_model_filter_build_level (filter, level, elt, FALSE); + gtk_tree_model_filter_build_level (filter, level, + FILTER_LEVEL_ELT_INDEX (level, elt), + FALSE); if (!level || level->visible_nodes <= filter_indices[i]) { diff --git a/gtk/gtktreemodelsort.c b/gtk/gtktreemodelsort.c index 1dbdda41f8..f07795cc23 100644 --- a/gtk/gtktreemodelsort.c +++ b/gtk/gtktreemodelsort.c @@ -67,7 +67,7 @@ struct _SortLevel { GArray *array; gint ref_count; - SortElt *parent_elt; + gint parent_elt_index; SortLevel *parent_level; }; @@ -101,6 +101,10 @@ enum { #define SORT_ELT(sort_elt) ((SortElt *)sort_elt) #define SORT_LEVEL(sort_level) ((SortLevel *)sort_level) +#define SORT_LEVEL_PARENT_ELT(level) (&g_array_index (SORT_LEVEL ((level))->parent_level->array, SortElt, SORT_LEVEL ((level))->parent_elt_index)) +#define SORT_LEVEL_ELT_INDEX(level, elt) (SORT_ELT ((elt)) - SORT_ELT (SORT_LEVEL ((level))->array->data)) + + #define GET_CHILD_ITER(tree_model_sort,ch_iter,so_iter) gtk_tree_model_sort_convert_iter_to_child_iter((GtkTreeModelSort*)(tree_model_sort), (ch_iter), (so_iter)); #define NO_SORT_FUNC ((GtkTreeIterCompareFunc) 0x1) @@ -211,7 +215,7 @@ static gboolean gtk_tree_model_sort_has_default_sort_func (GtkTreeSortable /* Private functions (sort funcs, level handling and other utils) */ static void gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort, SortLevel *parent_level, - SortElt *parent_elt); + gint parent_elt_index); static void gtk_tree_model_sort_free_level (GtkTreeModelSort *tree_model_sort, SortLevel *sort_level); static void gtk_tree_model_sort_increment_stamp (GtkTreeModelSort *tree_model_sort); @@ -499,7 +503,7 @@ gtk_tree_model_sort_row_changed (GtkTreeModel *s_model, for (i = 0; i < level->array->len; i++) if (g_array_index (level->array, SortElt, i).children) - g_array_index (level->array, SortElt, i).children->parent_elt = &g_array_index (level->array, SortElt, i); + g_array_index (level->array, SortElt, i).children->parent_elt_index = i; gtk_tree_path_up (path); gtk_tree_path_append_index (path, index); @@ -539,11 +543,11 @@ gtk_tree_model_sort_row_changed (GtkTreeModel *s_model, /* else? shouldn't really happen */ } - if (level->parent_elt) + if (level->parent_elt_index >= 0) { iter.stamp = tree_model_sort->stamp; iter.user_data = level->parent_level; - iter.user_data2 = level->parent_elt; + iter.user_data2 = SORT_LEVEL_PARENT_ELT (level); tmppath = gtk_tree_model_get_path (GTK_TREE_MODEL (tree_model_sort), &iter); @@ -609,7 +613,7 @@ gtk_tree_model_sort_row_inserted (GtkTreeModel *s_model, if (!tree_model_sort->root) { - gtk_tree_model_sort_build_level (tree_model_sort, NULL, NULL); + gtk_tree_model_sort_build_level (tree_model_sort, NULL, -1); /* the build level already put the inserted iter in the level, so no need to handle this signal anymore */ @@ -785,7 +789,7 @@ gtk_tree_model_sort_row_deleted (GtkTreeModel *s_model, if (elt->offset > offset) elt->offset--; if (elt->children) - elt->children->parent_elt = elt; + elt->children->parent_elt_index = i; } gtk_tree_path_free (path); @@ -934,7 +938,7 @@ gtk_tree_model_sort_get_iter (GtkTreeModel *tree_model, indices = gtk_tree_path_get_indices (path); if (tree_model_sort->root == NULL) - gtk_tree_model_sort_build_level (tree_model_sort, NULL, NULL); + gtk_tree_model_sort_build_level (tree_model_sort, NULL, -1); level = SORT_LEVEL (tree_model_sort->root); depth = gtk_tree_path_get_depth (path); @@ -948,7 +952,7 @@ gtk_tree_model_sort_get_iter (GtkTreeModel *tree_model, return FALSE; if (g_array_index (level->array, SortElt, indices[i]).children == NULL) - gtk_tree_model_sort_build_level (tree_model_sort, level, &g_array_index (level->array, SortElt, indices[i])); + gtk_tree_model_sort_build_level (tree_model_sort, level, indices[i]); level = g_array_index (level->array, SortElt, indices[i]).children; } @@ -972,19 +976,21 @@ gtk_tree_model_sort_get_path (GtkTreeModel *tree_model, GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model; GtkTreePath *retval; SortLevel *level; - SortElt *elt; + gint elt_index; g_return_val_if_fail (tree_model_sort->child_model != NULL, NULL); g_return_val_if_fail (tree_model_sort->stamp == iter->stamp, NULL); retval = gtk_tree_path_new (); - level = iter->user_data; - elt = iter->user_data2; - while (level != NULL) - { - gtk_tree_path_prepend_index (retval, elt - (SortElt *)level->array->data); - elt = level->parent_elt; + level = SORT_LEVEL (iter->user_data); + elt_index = SORT_LEVEL_ELT_INDEX (level, iter->user_data2); + + while (level) + { + gtk_tree_path_prepend_index (retval, elt_index); + + elt_index = level->parent_elt_index; level = level->parent_level; } @@ -1048,7 +1054,7 @@ gtk_tree_model_sort_iter_children (GtkTreeModel *tree_model, if (parent == NULL) { if (tree_model_sort->root == NULL) - gtk_tree_model_sort_build_level (tree_model_sort, NULL, NULL); + gtk_tree_model_sort_build_level (tree_model_sort, NULL, -1); if (tree_model_sort->root == NULL) return FALSE; @@ -1059,15 +1065,21 @@ gtk_tree_model_sort_iter_children (GtkTreeModel *tree_model, } else { - if (((SortElt *)parent->user_data2)->children == NULL) - gtk_tree_model_sort_build_level (tree_model_sort, - (SortLevel *)parent->user_data, - (SortElt *)parent->user_data2); - if (((SortElt *)parent->user_data2)->children == NULL) + SortElt *elt; + + level = SORT_LEVEL (parent->user_data); + elt = SORT_ELT (parent->user_data2); + + if (elt->children == NULL) + gtk_tree_model_sort_build_level (tree_model_sort, level, + SORT_LEVEL_ELT_INDEX (level, elt)); + + if (elt->children == NULL) return FALSE; + iter->stamp = tree_model_sort->stamp; - iter->user_data = ((SortElt *)parent->user_data2)->children; - iter->user_data2 = ((SortLevel *)iter->user_data)->array->data; + iter->user_data = elt->children; + iter->user_data2 = elt->children->array->data; } return TRUE; @@ -1160,7 +1172,7 @@ gtk_tree_model_sort_iter_parent (GtkTreeModel *tree_model, { iter->stamp = tree_model_sort->stamp; iter->user_data = level->parent_level; - iter->user_data2 = level->parent_elt; + iter->user_data2 = SORT_LEVEL_PARENT_ELT (level); return TRUE; } @@ -1173,9 +1185,9 @@ gtk_tree_model_sort_ref_node (GtkTreeModel *tree_model, { GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model; GtkTreeIter child_iter; - GtkTreeIter tmp_iter; - SortLevel *level; + SortLevel *level, *parent_level; SortElt *elt; + gint parent_elt_index; g_return_if_fail (tree_model_sort->child_model != NULL); g_return_if_fail (VALID_ITER (iter, tree_model_sort)); @@ -1193,28 +1205,34 @@ gtk_tree_model_sort_ref_node (GtkTreeModel *tree_model, level->ref_count++; /* Increase the reference count of all parent elements */ - tmp_iter.stamp = tree_model_sort->stamp; - tmp_iter.user_data = level->parent_level; - tmp_iter.user_data2 = level->parent_elt;; + parent_level = level->parent_level; + parent_elt_index = level->parent_elt_index; - while (tmp_iter.user_data2) + while (parent_level) { + GtkTreeIter tmp_iter; + + tmp_iter.stamp = tree_model_sort->stamp; + tmp_iter.user_data = parent_level; + tmp_iter.user_data2 = &g_array_index (parent_level->array, SortElt, parent_elt_index); + gtk_tree_model_sort_ref_node (tree_model, &tmp_iter); - tmp_iter.user_data2 = SORT_LEVEL (tmp_iter.user_data)->parent_elt; - tmp_iter.user_data = SORT_LEVEL (tmp_iter.user_data)->parent_level; + parent_elt_index = parent_level->parent_elt_index; + parent_level = parent_level->parent_level; } if (level->ref_count == 1) { SortLevel *parent_level = level->parent_level; - SortElt *parent_elt = level->parent_elt; + gint parent_elt_index = level->parent_elt_index; + /* We were at zero -- time to decrement the zero_ref_count val */ while (parent_level) - { - parent_elt->zero_ref_count--; + { + g_array_index (parent_level->array, SortElt, parent_elt_index).zero_ref_count--; - parent_elt = parent_level->parent_elt; + parent_elt_index = parent_level->parent_elt_index; parent_level = parent_level->parent_level; } @@ -1229,9 +1247,9 @@ gtk_tree_model_sort_real_unref_node (GtkTreeModel *tree_model, gboolean propagate_unref) { GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model; - GtkTreeIter tmp_iter; - SortLevel *level; + SortLevel *level, *parent_level; SortElt *elt; + gint parent_elt_index; g_return_if_fail (tree_model_sort->child_model != NULL); g_return_if_fail (VALID_ITER (iter, tree_model_sort)); @@ -1253,29 +1271,34 @@ gtk_tree_model_sort_real_unref_node (GtkTreeModel *tree_model, level->ref_count--; /* Decrease the reference count of all parent elements */ - tmp_iter.stamp = tree_model_sort->stamp; - tmp_iter.user_data = level->parent_level; - tmp_iter.user_data2 = level->parent_elt;; + parent_level = level->parent_level; + parent_elt_index = level->parent_elt_index; - while (tmp_iter.user_data2) + while (parent_level) { + GtkTreeIter tmp_iter; + + tmp_iter.stamp = tree_model_sort->stamp; + tmp_iter.user_data = parent_level; + tmp_iter.user_data2 = &g_array_index (parent_level->array, SortElt, parent_elt_index); + gtk_tree_model_sort_real_unref_node (tree_model, &tmp_iter, FALSE); - tmp_iter.user_data2 = SORT_LEVEL (tmp_iter.user_data)->parent_elt; - tmp_iter.user_data = SORT_LEVEL (tmp_iter.user_data)->parent_level; + parent_elt_index = parent_level->parent_elt_index; + parent_level = parent_level->parent_level; } if (level->ref_count == 0) { SortLevel *parent_level = level->parent_level; - SortElt *parent_elt = level->parent_elt; + gint parent_elt_index = level->parent_elt_index; /* We are at zero -- time to increment the zero_ref_count val */ while (parent_level) { - parent_elt->zero_ref_count++; + g_array_index (parent_level->array, SortElt, parent_elt_index).zero_ref_count++; - parent_elt = parent_level->parent_elt; + parent_elt_index = parent_level->parent_elt_index; parent_level = parent_level->parent_level; } @@ -1558,10 +1581,10 @@ gtk_tree_model_sort_sort_level (GtkTreeModelSort *tree_model_sort, /* Set up data */ data.tree_model_sort = tree_model_sort; - if (level->parent_elt) + if (level->parent_elt_index >= 0) { data.parent_path = gtk_tree_model_sort_elt_get_path (level->parent_level, - level->parent_elt); + SORT_LEVEL_PARENT_ELT (level)); gtk_tree_path_append_index (data.parent_path, 0); } else @@ -1627,9 +1650,8 @@ gtk_tree_model_sort_sort_level (GtkTreeModelSort *tree_model_sort, new_order[i] = g_array_index (sort_array, SortTuple, i).offset; g_array_append_val (new_array, *elt); - elt = &g_array_index (new_array, SortElt, i); if (elt->children) - elt->children->parent_elt = elt; + elt->children->parent_elt_index = i; } g_array_free (level->array, TRUE); @@ -1639,11 +1661,11 @@ gtk_tree_model_sort_sort_level (GtkTreeModelSort *tree_model_sort, if (emit_reordered) { gtk_tree_model_sort_increment_stamp (tree_model_sort); - if (level->parent_elt) + if (level->parent_elt_index >= 0) { iter.stamp = tree_model_sort->stamp; iter.user_data = level->parent_level; - iter.user_data2 = level->parent_elt; + iter.user_data2 = SORT_LEVEL_PARENT_ELT (level); path = gtk_tree_model_get_path (GTK_TREE_MODEL (tree_model_sort), &iter); @@ -1846,7 +1868,7 @@ gtk_tree_model_sort_insert_value (GtkTreeModelSort *tree_model_sort, tmp_elt = SORT_ELT (level->array->data); for (i = 0; i < level->array->len; i++, tmp_elt++) if (tmp_elt->children) - tmp_elt->children->parent_elt = tmp_elt; + tmp_elt->children->parent_elt_index = i; return TRUE; } @@ -1869,7 +1891,10 @@ gtk_tree_model_sort_elt_get_path (SortLevel *level, { gtk_tree_path_prepend_index (path, walker2->offset); - walker2 = walker->parent_elt; + if (!walker->parent_level) + break; + + walker2 = SORT_LEVEL_PARENT_ELT (walker); walker = walker->parent_level; } @@ -1992,7 +2017,7 @@ gtk_real_tree_model_sort_convert_child_path_to_path (GtkTreeModelSort *tree_mode child_indices = gtk_tree_path_get_indices (child_path); if (tree_model_sort->root == NULL && build_levels) - gtk_tree_model_sort_build_level (tree_model_sort, NULL, NULL); + gtk_tree_model_sort_build_level (tree_model_sort, NULL, -1); level = SORT_LEVEL (tree_model_sort->root); for (i = 0; i < gtk_tree_path_get_depth (child_path); i++) @@ -2018,7 +2043,7 @@ gtk_real_tree_model_sort_convert_child_path_to_path (GtkTreeModelSort *tree_mode gtk_tree_path_append_index (retval, j); if (g_array_index (level->array, SortElt, j).children == NULL && build_levels) { - gtk_tree_model_sort_build_level (tree_model_sort, level, &g_array_index (level->array, SortElt, j)); + gtk_tree_model_sort_build_level (tree_model_sort, level, j); } level = g_array_index (level->array, SortElt, j).children; found_child = TRUE; @@ -2084,6 +2109,7 @@ gtk_tree_model_sort_convert_child_iter_to_iter (GtkTreeModelSort *tree_model_sor g_return_val_if_fail (tree_model_sort->child_model != NULL, FALSE); g_return_val_if_fail (sort_iter != NULL, FALSE); g_return_val_if_fail (child_iter != NULL, FALSE); + g_return_val_if_fail (sort_iter != child_iter, FALSE); sort_iter->stamp = 0; @@ -2135,7 +2161,7 @@ gtk_tree_model_sort_convert_path_to_child_path (GtkTreeModelSort *tree_model_sor retval = gtk_tree_path_new (); sorted_indices = gtk_tree_path_get_indices (sorted_path); if (tree_model_sort->root == NULL) - gtk_tree_model_sort_build_level (tree_model_sort, NULL, NULL); + gtk_tree_model_sort_build_level (tree_model_sort, NULL, -1); level = SORT_LEVEL (tree_model_sort->root); for (i = 0; i < gtk_tree_path_get_depth (sorted_path); i++) @@ -2150,7 +2176,7 @@ gtk_tree_model_sort_convert_path_to_child_path (GtkTreeModelSort *tree_model_sor } if (g_array_index (level->array, SortElt, count).children == NULL) - gtk_tree_model_sort_build_level (tree_model_sort, level, &g_array_index (level->array, SortElt, count)); + gtk_tree_model_sort_build_level (tree_model_sort, level, count); if (level == NULL) { @@ -2182,6 +2208,7 @@ gtk_tree_model_sort_convert_iter_to_child_iter (GtkTreeModelSort *tree_model_sor g_return_if_fail (tree_model_sort->child_model != NULL); g_return_if_fail (child_iter != NULL); g_return_if_fail (VALID_ITER (sorted_iter, tree_model_sort)); + g_return_if_fail (sorted_iter != child_iter); if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort)) { @@ -2201,9 +2228,10 @@ gtk_tree_model_sort_convert_iter_to_child_iter (GtkTreeModelSort *tree_model_sor static void gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort, SortLevel *parent_level, - SortElt *parent_elt) + gint parent_elt_index) { GtkTreeIter iter; + SortElt *parent_elt = NULL; SortLevel *new_level; gint length = 0; gint i; @@ -2221,6 +2249,8 @@ gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort, GtkTreeIter parent_iter; GtkTreeIter child_parent_iter; + parent_elt = &g_array_index (parent_level->array, SortElt, parent_elt_index); + parent_iter.stamp = tree_model_sort->stamp; parent_iter.user_data = parent_level; parent_iter.user_data2 = parent_elt; @@ -2246,10 +2276,10 @@ gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort, new_level = g_new (SortLevel, 1); new_level->array = g_array_sized_new (FALSE, FALSE, sizeof (SortElt), length); new_level->ref_count = 0; - new_level->parent_elt = parent_elt; new_level->parent_level = parent_level; + new_level->parent_elt_index = parent_elt_index; - if (parent_elt) + if (parent_elt_index >= 0) parent_elt->children = new_level; else tree_model_sort->root = new_level; @@ -2257,11 +2287,12 @@ gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort, /* increase the count of zero ref_counts.*/ while (parent_level) { - parent_elt->zero_ref_count++; + g_array_index (parent_level->array, SortElt, parent_elt_index).zero_ref_count++; - parent_elt = parent_level->parent_elt; + parent_elt_index = parent_level->parent_elt_index; parent_level = parent_level->parent_level; } + if (new_level != tree_model_sort->root) tree_model_sort->zero_ref_count++; @@ -2332,13 +2363,13 @@ gtk_tree_model_sort_free_level (GtkTreeModelSort *tree_model_sort, if (sort_level->ref_count == 0) { SortLevel *parent_level = sort_level->parent_level; - SortElt *parent_elt = sort_level->parent_elt; + gint parent_elt_index = sort_level->parent_elt_index; while (parent_level) - { - parent_elt->zero_ref_count--; + { + g_array_index (parent_level->array, SortElt, parent_elt_index).zero_ref_count--; - parent_elt = parent_level->parent_elt; + parent_elt_index = parent_level->parent_elt_index; parent_level = parent_level->parent_level; } @@ -2346,8 +2377,8 @@ gtk_tree_model_sort_free_level (GtkTreeModelSort *tree_model_sort, tree_model_sort->zero_ref_count--; } - if (sort_level->parent_elt) - sort_level->parent_elt->children = NULL; + if (sort_level->parent_elt_index >= 0) + SORT_LEVEL_PARENT_ELT (sort_level)->children = NULL; else tree_model_sort->root = NULL; diff --git a/gtk/gtktreestore.c b/gtk/gtktreestore.c index 1fb178d375..30ff14f810 100644 --- a/gtk/gtktreestore.c +++ b/gtk/gtktreestore.c @@ -358,30 +358,20 @@ static void gtk_tree_store_set_n_columns (GtkTreeStore *tree_store, gint n_columns) { - GType *new_columns; + int i; if (tree_store->n_columns == n_columns) return; - new_columns = g_new0 (GType, n_columns); - if (tree_store->column_headers) - { - /* copy the old header orders over */ - if (n_columns >= tree_store->n_columns) - memcpy (new_columns, tree_store->column_headers, tree_store->n_columns * sizeof (gchar *)); - else - memcpy (new_columns, tree_store->column_headers, n_columns * sizeof (GType)); - - g_free (tree_store->column_headers); - } + tree_store->column_headers = g_renew (GType, tree_store->column_headers, n_columns); + for (i = tree_store->n_columns; i < n_columns; i++) + tree_store->column_headers[i] = G_TYPE_INVALID; + tree_store->n_columns = n_columns; if (tree_store->sort_list) _gtk_tree_data_list_header_free (tree_store->sort_list); tree_store->sort_list = _gtk_tree_data_list_header_new (n_columns, tree_store->column_headers); - - tree_store->column_headers = new_columns; - tree_store->n_columns = n_columns; } /** @@ -620,7 +610,10 @@ gtk_tree_store_iter_next (GtkTreeModel *tree_model, return TRUE; } else - return FALSE; + { + iter->stamp = 0; + return FALSE; + } } static gboolean @@ -646,7 +639,10 @@ gtk_tree_store_iter_children (GtkTreeModel *tree_model, return TRUE; } else - return FALSE; + { + iter->stamp = 0; + return FALSE; + } } static gboolean @@ -708,7 +704,10 @@ gtk_tree_store_iter_nth_child (GtkTreeModel *tree_model, return TRUE; } else - return FALSE; + { + iter->stamp = 0; + return FALSE; + } } static gboolean @@ -733,7 +732,10 @@ gtk_tree_store_iter_parent (GtkTreeModel *tree_model, return TRUE; } else - return FALSE; + { + iter->stamp = 0; + return FALSE; + } } diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c index 6ad1f89a25..a0fdf33072 100644 --- a/gtk/gtktreeview.c +++ b/gtk/gtktreeview.c @@ -345,15 +345,6 @@ static void gtk_tree_view_build_tree (GtkTreeView GtkTreeIter *iter, gint depth, gboolean recurse); -static gboolean gtk_tree_view_discover_dirty_iter (GtkTreeView *tree_view, - GtkTreeIter *iter, - gint depth, - gint *height, - GtkRBNode *node); -static void gtk_tree_view_discover_dirty (GtkTreeView *tree_view, - GtkRBTree *tree, - GtkTreeIter *iter, - gint depth); static void gtk_tree_view_clamp_node_visible (GtkTreeView *tree_view, GtkRBTree *tree, GtkRBNode *node); @@ -2043,9 +2034,8 @@ gtk_tree_view_size_request (GtkWidget *widget, GtkTreeView *tree_view = GTK_TREE_VIEW (widget); GList *tmp_list; - /* we validate GTK_TREE_VIEW_TIME_MS_PER_IDLE rows initially just to make - * sure we have some size. In practice, with a lot of static lists, this - * should get a good width. + /* we validate some rows initially just to make sure we have some size. + * In practice, with a lot of static lists, this should get a good width. */ do_validate_rows (tree_view, FALSE); gtk_tree_view_size_request_columns (tree_view); @@ -4582,78 +4572,6 @@ gtk_tree_view_bin_expose (GtkWidget *widget, background_area.y + max_height); } - if (gtk_tree_view_is_expander_column (tree_view, column) && - tree_view->priv->tree_lines_enabled) - { - gint x = background_area.x; - gint mult = rtl ? -1 : 1; - gint y0 = background_area.y; - gint y1 = background_area.y + background_area.height/2; - gint y2 = background_area.y + background_area.height; - - if (rtl) - x += background_area.width - 1; - - if ((node->flags & GTK_RBNODE_IS_PARENT) == GTK_RBNODE_IS_PARENT - && depth > 1) - { - gdk_draw_line (event->window, - tree_view->priv->tree_line_gc, - x + tree_view->priv->expander_size * (depth - 1.5) * mult, - y1, - x + tree_view->priv->expander_size * (depth - 1.1) * mult, - y1); - } - else if (depth > 1) - { - gdk_draw_line (event->window, - tree_view->priv->tree_line_gc, - x + tree_view->priv->expander_size * (depth - 1.5) * mult, - y1, - x + tree_view->priv->expander_size * (depth - 0.5) * mult, - y1); - } - - if (depth > 1) - { - gint i; - GtkRBNode *tmp_node; - GtkRBTree *tmp_tree; - - if (!_gtk_rbtree_next (tree, node)) - gdk_draw_line (event->window, - tree_view->priv->tree_line_gc, - x + tree_view->priv->expander_size * (depth - 1.5) * mult, - y0, - x + tree_view->priv->expander_size * (depth - 1.5) * mult, - y1); - else - gdk_draw_line (event->window, - tree_view->priv->tree_line_gc, - x + tree_view->priv->expander_size * (depth - 1.5) * mult, - y0, - x + tree_view->priv->expander_size * (depth - 1.5) * mult, - y2); - - tmp_node = tree->parent_node; - tmp_tree = tree->parent_tree; - - for (i = depth - 2; i > 0; i--) - { - if (_gtk_rbtree_next (tmp_tree, tmp_node)) - gdk_draw_line (event->window, - tree_view->priv->tree_line_gc, - x + tree_view->priv->expander_size * (i - 0.5) * mult, - y0, - x + tree_view->priv->expander_size * (i - 0.5) * mult, - y2); - - tmp_node = tmp_tree->parent_node; - tmp_tree = tmp_tree->parent_tree; - } - } - } - if (gtk_tree_view_is_expander_column (tree_view, column)) { if (!rtl) @@ -4727,6 +4645,79 @@ gtk_tree_view_bin_expose (GtkWidget *widget, &event->area, flags); } + + if (gtk_tree_view_is_expander_column (tree_view, column) && + tree_view->priv->tree_lines_enabled) + { + gint x = background_area.x; + gint mult = rtl ? -1 : 1; + gint y0 = background_area.y; + gint y1 = background_area.y + background_area.height/2; + gint y2 = background_area.y + background_area.height; + + if (rtl) + x += background_area.width - 1; + + if ((node->flags & GTK_RBNODE_IS_PARENT) == GTK_RBNODE_IS_PARENT + && depth > 1) + { + gdk_draw_line (event->window, + tree_view->priv->tree_line_gc, + x + tree_view->priv->expander_size * (depth - 1.5) * mult, + y1, + x + tree_view->priv->expander_size * (depth - 1.1) * mult, + y1); + } + else if (depth > 1) + { + gdk_draw_line (event->window, + tree_view->priv->tree_line_gc, + x + tree_view->priv->expander_size * (depth - 1.5) * mult, + y1, + x + tree_view->priv->expander_size * (depth - 0.5) * mult, + y1); + } + + if (depth > 1) + { + gint i; + GtkRBNode *tmp_node; + GtkRBTree *tmp_tree; + + if (!_gtk_rbtree_next (tree, node)) + gdk_draw_line (event->window, + tree_view->priv->tree_line_gc, + x + tree_view->priv->expander_size * (depth - 1.5) * mult, + y0, + x + tree_view->priv->expander_size * (depth - 1.5) * mult, + y1); + else + gdk_draw_line (event->window, + tree_view->priv->tree_line_gc, + x + tree_view->priv->expander_size * (depth - 1.5) * mult, + y0, + x + tree_view->priv->expander_size * (depth - 1.5) * mult, + y2); + + tmp_node = tree->parent_node; + tmp_tree = tree->parent_tree; + + for (i = depth - 2; i > 0; i--) + { + if (_gtk_rbtree_next (tmp_tree, tmp_node)) + gdk_draw_line (event->window, + tree_view->priv->tree_line_gc, + x + tree_view->priv->expander_size * (i - 0.5) * mult, + y0, + x + tree_view->priv->expander_size * (i - 0.5) * mult, + y2); + + tmp_node = tmp_tree->parent_node; + tmp_tree = tmp_tree->parent_tree; + } + } + } + if (node == cursor && has_special_cell && ((column == tree_view->priv->focus_column && GTK_TREE_VIEW_FLAG_SET (tree_view, GTK_TREE_VIEW_DRAW_KEYFOCUS) && @@ -4740,6 +4731,7 @@ gtk_tree_view_bin_expose (GtkWidget *widget, &event->area, flags); } + cell_offset += column->width; } @@ -5483,6 +5475,12 @@ gtk_tree_view_enter_notify (GtkWidget *widget, if (tree_view->priv->tree == NULL) return FALSE; + if (event->mode == GDK_CROSSING_GRAB || + event->mode == GDK_CROSSING_GTK_GRAB || + event->mode == GDK_CROSSING_GTK_UNGRAB || + event->mode == GDK_CROSSING_STATE_CHANGED) + return TRUE; + /* find the node internally */ new_y = TREE_WINDOW_Y_TO_RBTREE_Y(tree_view, event->y); if (new_y < 0) @@ -5992,16 +5990,24 @@ validate_visible_area (GtkTreeView *tree_view) while (area_above > 0) { _gtk_rbtree_prev_full (tree, node, &tree, &node); - if (! gtk_tree_path_prev (above_path) && node != NULL) - { - gtk_tree_path_free (above_path); - above_path = _gtk_tree_view_find_path (tree_view, tree, node); - } - gtk_tree_model_get_iter (tree_view->priv->model, &iter, above_path); + + /* Always find the new path in the tree. We cannot just assume + * a gtk_tree_path_prev() is enough here, as there might be children + * in between this node and the previous sibling node. If this + * appears to be a performance hotspot in profiles, we can look into + * intrigate logic for keeping path, node and iter in sync like + * we do for forward walks. (Which will be hard because of the lacking + * iter_prev). + */ if (node == NULL) break; + gtk_tree_path_free (above_path); + above_path = _gtk_tree_view_find_path (tree_view, tree, node); + + gtk_tree_model_get_iter (tree_view->priv->model, &iter, above_path); + if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID) || GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID)) { @@ -6242,7 +6248,7 @@ do_validate_rows (GtkTreeView *tree_view, gboolean queue_resize) gtk_adjustment_changed (tree_view->priv->vadjustment); if (queue_resize) - gtk_widget_queue_resize_no_redraw (GTK_WIDGET (tree_view)); + gtk_widget_queue_resize (GTK_WIDGET (tree_view)); } if (path) gtk_tree_path_free (path); @@ -6426,6 +6432,10 @@ gtk_tree_view_top_row_to_dy (GtkTreeView *tree_view) GtkRBNode *node; int new_dy; + /* Avoid recursive calls */ + if (tree_view->priv->in_top_row_to_dy) + return; + if (tree_view->priv->top_row) path = gtk_tree_row_reference_get_path (tree_view->priv->top_row); else @@ -8762,133 +8772,6 @@ gtk_tree_view_build_tree (GtkTreeView *tree_view, gtk_tree_path_free (path); } -/* If height is non-NULL, then we set it to be the new height. if it's all - * dirty, then height is -1. We know we'll remeasure dirty rows, anyways. - */ -static gboolean -gtk_tree_view_discover_dirty_iter (GtkTreeView *tree_view, - GtkTreeIter *iter, - gint depth, - gint *height, - GtkRBNode *node) -{ - GtkTreeViewColumn *column; - GList *list; - gboolean retval = FALSE; - gint tmpheight; - gint horizontal_separator; - - gtk_widget_style_get (GTK_WIDGET (tree_view), - "horizontal-separator", &horizontal_separator, - NULL); - - if (height) - *height = -1; - - for (list = tree_view->priv->columns; list; list = list->next) - { - gint width; - column = list->data; - if (column->dirty == TRUE) - continue; - if (height == NULL && column->column_type == GTK_TREE_VIEW_COLUMN_FIXED) - continue; - if (!column->visible) - continue; - - gtk_tree_view_column_cell_set_cell_data (column, tree_view->priv->model, iter, - GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_PARENT), - node->children?TRUE:FALSE); - - if (height) - { - gtk_tree_view_column_cell_get_size (column, - NULL, NULL, NULL, - &width, &tmpheight); - *height = MAX (*height, tmpheight); - } - else - { - gtk_tree_view_column_cell_get_size (column, - NULL, NULL, NULL, - &width, NULL); - } - - if (gtk_tree_view_is_expander_column (tree_view, column)) - { - int tmp = 0; - - tmp = horizontal_separator + width + (depth - 1) * tree_view->priv->level_indentation; - if (TREE_VIEW_DRAW_EXPANDERS (tree_view)) - tmp += depth * tree_view->priv->expander_size; - - if (tmp > column->requested_width) - { - _gtk_tree_view_column_cell_set_dirty (column, TRUE); - retval = TRUE; - } - } - else - { - if (horizontal_separator + width > column->requested_width) - { - _gtk_tree_view_column_cell_set_dirty (column, TRUE); - retval = TRUE; - } - } - } - - return retval; -} - -static void -gtk_tree_view_discover_dirty (GtkTreeView *tree_view, - GtkRBTree *tree, - GtkTreeIter *iter, - gint depth) -{ - GtkRBNode *temp = tree->root; - GtkTreeViewColumn *column; - GList *list; - GtkTreeIter child; - gboolean is_all_dirty; - - TREE_VIEW_INTERNAL_ASSERT_VOID (tree != NULL); - - while (temp->left != tree->nil) - temp = temp->left; - - do - { - TREE_VIEW_INTERNAL_ASSERT_VOID (temp != NULL); - is_all_dirty = TRUE; - for (list = tree_view->priv->columns; list; list = list->next) - { - column = list->data; - if (column->dirty == FALSE) - { - is_all_dirty = FALSE; - break; - } - } - - if (is_all_dirty) - return; - - gtk_tree_view_discover_dirty_iter (tree_view, - iter, - depth, - NULL, - temp); - if (gtk_tree_model_iter_children (tree_view->priv->model, &child, iter) && - temp->children != NULL) - gtk_tree_view_discover_dirty (tree_view, temp->children, &child, depth + 1); - temp = _gtk_rbtree_next (tree, temp); - } - while (gtk_tree_model_iter_next (tree_view->priv->model, iter)); -} - - /* Make sure the node is visible vertically */ static void gtk_tree_view_clamp_node_visible (GtkTreeView *tree_view, @@ -9868,6 +9751,8 @@ gtk_tree_view_move_cursor_page_up_down (GtkTreeView *tree_view, if (!gtk_tree_path_compare (old_cursor_path, cursor_path)) gtk_widget_error_bell (GTK_WIDGET (tree_view)); + gtk_widget_grab_focus (GTK_WIDGET (tree_view)); + cleanup: gtk_tree_path_free (old_cursor_path); gtk_tree_path_free (cursor_path); @@ -9962,6 +9847,7 @@ gtk_tree_view_move_cursor_left_right (GtkTreeView *tree_view, cursor_node, NULL); g_signal_emit (tree_view, tree_view_signals[CURSOR_CHANGED], 0); + gtk_widget_grab_focus (GTK_WIDGET (tree_view)); } else { @@ -10027,6 +9913,7 @@ gtk_tree_view_move_cursor_start_end (GtkTreeView *tree_view, if (gtk_tree_path_compare (old_path, path)) { gtk_tree_view_real_set_cursor (tree_view, path, TRUE, TRUE); + gtk_widget_grab_focus (GTK_WIDGET (tree_view)); } else { @@ -10648,6 +10535,9 @@ gtk_tree_view_adjustment_changed (GtkAdjustment *adjustment, if (!tree_view->priv->in_top_row_to_dy) gtk_tree_view_dy_to_top_row (tree_view); } + + gdk_window_process_updates (tree_view->priv->header_window, TRUE); + gdk_window_process_updates (tree_view->priv->bin_window, TRUE); } } @@ -12557,14 +12447,24 @@ gtk_tree_view_real_set_cursor (GtkTreeView *tree_view, gtk_tree_row_reference_free (tree_view->priv->cursor); tree_view->priv->cursor = NULL; - /* One cannot set the cursor on a separator. */ - if (!row_is_separator (tree_view, NULL, path)) + /* One cannot set the cursor on a separator. Also, if + * _gtk_tree_view_find_node returns TRUE, it ran out of tree + * before finding the tree and node belonging to path. The + * path maps to a non-existing path and we will silently bail out. + * We unset tree and node to avoid further processing. + */ + if (!row_is_separator (tree_view, NULL, path) + && _gtk_tree_view_find_node (tree_view, path, &tree, &node) == FALSE) { tree_view->priv->cursor = - gtk_tree_row_reference_new_proxy (G_OBJECT (tree_view), - tree_view->priv->model, - path); - _gtk_tree_view_find_node (tree_view, path, &tree, &node); + gtk_tree_row_reference_new_proxy (G_OBJECT (tree_view), + tree_view->priv->model, + path); + } + else + { + tree = NULL; + node = NULL; } if (tree != NULL) @@ -12654,6 +12554,9 @@ gtk_tree_view_get_cursor (GtkTreeView *tree_view, * This function is often followed by @gtk_widget_grab_focus (@tree_view) * in order to give keyboard focus to the widget. Please note that editing * can only happen when the widget is realized. + * + * If @path is invalid for @model, the current cursor (if any) will be unset + * and the function will return without failing. **/ void gtk_tree_view_set_cursor (GtkTreeView *tree_view, @@ -12685,6 +12588,9 @@ gtk_tree_view_set_cursor (GtkTreeView *tree_view, * widget. Please note that editing can only happen when the widget is * realized. * + * If @path is invalid for @model, the current cursor (if any) will be unset + * and the function will return without failing. + * * Since: 2.2 **/ void @@ -12695,9 +12601,12 @@ gtk_tree_view_set_cursor_on_cell (GtkTreeView *tree_view, gboolean start_editing) { g_return_if_fail (GTK_IS_TREE_VIEW (tree_view)); - g_return_if_fail (tree_view->priv->tree != NULL); g_return_if_fail (path != NULL); g_return_if_fail (focus_column == NULL || GTK_IS_TREE_VIEW_COLUMN (focus_column)); + + if (!tree_view->priv->model) + return; + if (focus_cell) { g_return_if_fail (focus_column); @@ -12770,7 +12679,8 @@ gtk_tree_view_get_bin_window (GtkTreeView *tree_view) * with the column at that point. @cell_x and @cell_y return the coordinates * relative to the cell background (i.e. the @background_area passed to * gtk_cell_renderer_render()). This function is only meaningful if - * @tree_view is realized. + * @tree_view is realized. Therefore this function will always return %FALSE + * if @tree_view is not realized or does not have a model. * * For converting widget coordinates (eg. the ones you get from * GtkWidget::query-tooltip), please see @@ -12792,13 +12702,15 @@ gtk_tree_view_get_path_at_pos (GtkTreeView *tree_view, gint y_offset; g_return_val_if_fail (tree_view != NULL, FALSE); - g_return_val_if_fail (tree_view->priv->bin_window != NULL, FALSE); if (path) *path = NULL; if (column) *column = NULL; + if (tree_view->priv->bin_window == NULL) + return FALSE; + if (tree_view->priv->tree == NULL) return FALSE; @@ -13621,9 +13533,12 @@ gtk_tree_view_get_drag_dest_row (GtkTreeView *tree_view, * @pos: Return location for the drop position, or %NULL * * Determines the destination row for a given position. @drag_x and - * @drag_y are expected to be in widget coordinates. + * @drag_y are expected to be in widget coordinates. This function is only + * meaningful if @tree_view is realized. Therefore this function will always + * return %FALSE if @tree_view is not realized or does not have a model. * - * Return value: whether there is a row at the given position. + * Return value: whether there is a row at the given position, %TRUE if this + * is indeed the case. **/ gboolean gtk_tree_view_get_dest_row_at_pos (GtkTreeView *tree_view, @@ -13647,12 +13562,13 @@ gtk_tree_view_get_dest_row_at_pos (GtkTreeView *tree_view, g_return_val_if_fail (tree_view != NULL, FALSE); g_return_val_if_fail (drag_x >= 0, FALSE); g_return_val_if_fail (drag_y >= 0, FALSE); - g_return_val_if_fail (tree_view->priv->bin_window != NULL, FALSE); - if (path) *path = NULL; + if (tree_view->priv->bin_window == NULL) + return FALSE; + if (tree_view->priv->tree == NULL) return FALSE; @@ -14592,8 +14508,8 @@ gtk_tree_view_search_iter (GtkTreeModel *model, { gtk_tree_view_scroll_to_cell (tree_view, path, NULL, TRUE, 0.5, 0.0); - gtk_tree_view_real_set_cursor (tree_view, path, FALSE, TRUE); gtk_tree_selection_select_iter (selection, iter); + gtk_tree_view_real_set_cursor (tree_view, path, FALSE, TRUE); if (path) gtk_tree_path_free (path); @@ -14679,7 +14595,6 @@ gtk_tree_view_search_init (GtkWidget *entry, GtkTreeView *tree_view) { gint ret; - gint len; gint count = 0; const gchar *text; GtkTreeIter iter; @@ -14690,7 +14605,7 @@ gtk_tree_view_search_init (GtkWidget *entry, g_return_if_fail (GTK_IS_TREE_VIEW (tree_view)); text = gtk_entry_get_text (GTK_ENTRY (entry)); - len = strlen (text); + model = gtk_tree_view_get_model (tree_view); selection = gtk_tree_view_get_selection (tree_view); @@ -14706,7 +14621,7 @@ gtk_tree_view_search_init (GtkWidget *entry, tree_view); } - if (len < 1) + if (*text == '\0') return; if (!gtk_tree_model_get_iter_first (model, &iter)) @@ -15099,6 +15014,10 @@ gtk_tree_view_set_row_separator_func (GtkTreeView *tree_view, tree_view->priv->row_separator_func = func; tree_view->priv->row_separator_data = data; tree_view->priv->row_separator_destroy = destroy; + + /* Have the tree recalculate heights */ + _gtk_rbtree_mark_invalid (tree_view->priv->tree); + gtk_widget_queue_resize (GTK_WIDGET (tree_view)); } diff --git a/gtk/gtktreeviewcolumn.c b/gtk/gtktreeviewcolumn.c index bf98fdf1ad..edec5deffe 100644 --- a/gtk/gtktreeviewcolumn.c +++ b/gtk/gtktreeviewcolumn.c @@ -51,7 +51,8 @@ enum PROP_ALIGNMENT, PROP_REORDERABLE, PROP_SORT_INDICATOR, - PROP_SORT_ORDER + PROP_SORT_ORDER, + PROP_SORT_COLUMN_ID }; enum @@ -325,7 +326,24 @@ gtk_tree_view_column_class_init (GtkTreeViewColumnClass *class) GTK_TYPE_SORT_TYPE, GTK_SORT_ASCENDING, GTK_PARAM_READWRITE)); - + + /** + * GtkTreeViewColumn:sort-column-id: + * + * Logical sort column ID this column sorts on when selected for sorting. Setting the sort column ID makes the column header + * clickable. Set to %-1 to make the column unsortable. + * + * Since: 2.18 + **/ + g_object_class_install_property (object_class, + PROP_SORT_COLUMN_ID, + g_param_spec_int ("sort-column-id", + P_("Sort column ID"), + P_("Logical sort column ID this column sorts on when selected for sorting"), + -1, + G_MAXINT, + -1, + GTK_PARAM_READWRITE)); } static void @@ -497,6 +515,11 @@ gtk_tree_view_column_set_property (GObject *object, g_value_get_enum (value)); break; + case PROP_SORT_COLUMN_ID: + gtk_tree_view_column_set_sort_column_id (tree_column, + g_value_get_int (value)); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -595,6 +618,11 @@ gtk_tree_view_column_get_property (GObject *object, gtk_tree_view_column_get_sort_order (tree_column)); break; + case PROP_SORT_COLUMN_ID: + g_value_set_int (value, + gtk_tree_view_column_get_sort_column_id (tree_column)); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1540,20 +1568,10 @@ gtk_tree_view_column_clear (GtkTreeViewColumn *tree_column) gtk_cell_layout_clear (GTK_CELL_LAYOUT (tree_column)); } -/** - * gtk_tree_view_column_get_cell_renderers: - * @tree_column: A #GtkTreeViewColumn - * - * Returns a newly-allocated #GList of all the cell renderers in the column, - * in no particular order. The list must be freed with g_list_free(). - * - * Return value: A list of #GtkCellRenderers - * - * Deprecated: 2.18: use gtk_cell_layout_get_cells() instead. - **/ -GList * -gtk_tree_view_column_get_cell_renderers (GtkTreeViewColumn *tree_column) +static GList * +gtk_tree_view_column_cell_layout_get_cells (GtkCellLayout *layout) { + GtkTreeViewColumn *tree_column = GTK_TREE_VIEW_COLUMN (layout); GList *retval = NULL, *list; g_return_val_if_fail (tree_column != NULL, NULL); @@ -1568,10 +1586,21 @@ gtk_tree_view_column_get_cell_renderers (GtkTreeViewColumn *tree_column) return retval; } -static GList * -gtk_tree_view_column_cell_layout_get_cells (GtkCellLayout *layout) +/** + * gtk_tree_view_column_get_cell_renderers: + * @tree_column: A #GtkTreeViewColumn + * + * Returns a newly-allocated #GList of all the cell renderers in the column, + * in no particular order. The list must be freed with g_list_free(). + * + * Return value: A list of #GtkCellRenderers + * + * Deprecated: 2.18: use gtk_cell_layout_get_cells() instead. + **/ +GList * +gtk_tree_view_column_get_cell_renderers (GtkTreeViewColumn *tree_column) { - return gtk_tree_view_column_get_cell_renderers (GTK_TREE_VIEW_COLUMN (layout)); + return gtk_tree_view_column_cell_layout_get_cells (GTK_CELL_LAYOUT (tree_column)); } /** @@ -2380,6 +2409,7 @@ gtk_tree_view_column_set_sort_column_id (GtkTreeViewColumn *tree_column, gtk_tree_view_column_set_sort_order (tree_column, GTK_SORT_ASCENDING); gtk_tree_view_column_set_sort_indicator (tree_column, FALSE); gtk_tree_view_column_set_clickable (tree_column, FALSE); + g_object_notify (G_OBJECT (tree_column), "sort-column-id"); return; } @@ -2392,6 +2422,7 @@ gtk_tree_view_column_set_sort_column_id (GtkTreeViewColumn *tree_column, NULL); gtk_tree_view_column_setup_sort_column_id_callback (tree_column); + g_object_notify (G_OBJECT (tree_column), "sort-column-id"); } /** diff --git a/gtk/gtktypeutils.c b/gtk/gtktypeutils.c index 986f9ff188..6047d6f218 100644 --- a/gtk/gtktypeutils.c +++ b/gtk/gtktypeutils.c @@ -125,6 +125,8 @@ gtk_type_init (GTypeDebugFlags debug_flags) if (!initialized) { + GType unused; + initialized = TRUE; /* initialize GLib type system @@ -133,7 +135,7 @@ gtk_type_init (GTypeDebugFlags debug_flags) /* GTK_TYPE_OBJECT */ - gtk_object_get_type (); + unused = gtk_object_get_type (); } } diff --git a/gtk/gtkvbbox.c b/gtk/gtkvbbox.c index 5198e46a30..72ba3851b5 100644 --- a/gtk/gtkvbbox.c +++ b/gtk/gtkvbbox.c @@ -21,7 +21,7 @@ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS * file for a list of people on the GTK+ Team. See the ChangeLog * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. */ #include "config.h" @@ -45,17 +45,13 @@ static void gtk_vbutton_box_init (GtkVButtonBox *vbutton_box) { gtk_orientable_set_orientation (GTK_ORIENTABLE (vbutton_box), - GTK_ORIENTATION_VERTICAL); + GTK_ORIENTATION_VERTICAL); } -GtkWidget* +GtkWidget * gtk_vbutton_box_new (void) { - GtkVButtonBox *vbutton_box; - - vbutton_box = g_object_new (GTK_TYPE_VBUTTON_BOX, NULL); - - return GTK_WIDGET (vbutton_box); + return g_object_new (GTK_TYPE_VBUTTON_BOX, NULL); } @@ -98,5 +94,12 @@ gtk_vbutton_box_get_layout_default (void) return default_layout_style; } +GtkButtonBoxStyle +_gtk_vbutton_box_get_layout_default (void) +{ + return default_layout_style; +} + + #define __GTK_VBBOX_C__ #include "gtkaliasdef.c" diff --git a/gtk/gtkvbbox.h b/gtk/gtkvbbox.h index 901bc709a7..996eb57a60 100644 --- a/gtk/gtkvbbox.h +++ b/gtk/gtkvbbox.h @@ -73,6 +73,8 @@ GtkButtonBoxStyle gtk_vbutton_box_get_layout_default (void); void gtk_vbutton_box_set_layout_default (GtkButtonBoxStyle layout); #endif +/* private API */ +GtkButtonBoxStyle _gtk_vbutton_box_get_layout_default (void); G_END_DECLS diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index e263660eb2..5677fd73f4 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -154,7 +154,8 @@ enum { PROP_HAS_TOOLTIP, PROP_TOOLTIP_MARKUP, PROP_TOOLTIP_TEXT, - PROP_WINDOW + PROP_WINDOW, + PROP_DOUBLE_BUFFERED }; typedef struct _GtkStateData GtkStateData; @@ -692,6 +693,21 @@ gtk_widget_class_init (GtkWidgetClass *klass) GDK_TYPE_WINDOW, GTK_PARAM_READABLE)); + /** + * GtkWidget:double-buffered + * + * Whether or not the widget is double buffered. + * + * Since: 2.18 + */ + g_object_class_install_property (gobject_class, + PROP_DOUBLE_BUFFERED, + g_param_spec_boolean ("double-buffered", + P_("Double Buffered"), + P_("Whether or not the widget is double buffered"), + TRUE, + GTK_PARAM_READWRITE)); + widget_signals[SHOW] = g_signal_new (I_("show"), G_TYPE_FROM_CLASS (gobject_class), @@ -2399,11 +2415,10 @@ gtk_widget_set_property (GObject *object, switch (prop_id) { gboolean tmp; - guint32 saved_flags; gchar *tooltip_markup; const gchar *tooltip_text; GtkWindow *tooltip_window; - + case PROP_NAME: gtk_widget_set_name (widget, g_value_get_string (value)); break; @@ -2417,10 +2432,7 @@ gtk_widget_set_property (GObject *object, gtk_widget_set_usize_internal (widget, -2, g_value_get_int (value)); break; case PROP_VISIBLE: - if (g_value_get_boolean (value)) - gtk_widget_show (widget); - else - gtk_widget_hide (widget); + gtk_widget_set_visible (widget, g_value_get_boolean (value)); break; case PROP_SENSITIVE: gtk_widget_set_sensitive (widget, g_value_get_boolean (value)); @@ -2429,13 +2441,7 @@ gtk_widget_set_property (GObject *object, gtk_widget_set_app_paintable (widget, g_value_get_boolean (value)); break; case PROP_CAN_FOCUS: - saved_flags = GTK_WIDGET_FLAGS (widget); - if (g_value_get_boolean (value)) - GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS); - else - GTK_WIDGET_UNSET_FLAGS (widget, GTK_CAN_FOCUS); - if (saved_flags != GTK_WIDGET_FLAGS (widget)) - gtk_widget_queue_resize (widget); + gtk_widget_set_can_focus (widget, g_value_get_boolean (value)); break; case PROP_HAS_FOCUS: if (g_value_get_boolean (value)) @@ -2446,23 +2452,14 @@ gtk_widget_set_property (GObject *object, gtk_widget_grab_focus (widget); break; case PROP_CAN_DEFAULT: - saved_flags = GTK_WIDGET_FLAGS (widget); - if (g_value_get_boolean (value)) - GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_DEFAULT); - else - GTK_WIDGET_UNSET_FLAGS (widget, GTK_CAN_DEFAULT); - if (saved_flags != GTK_WIDGET_FLAGS (widget)) - gtk_widget_queue_resize (widget); + gtk_widget_set_can_default (widget, g_value_get_boolean (value)); break; case PROP_HAS_DEFAULT: if (g_value_get_boolean (value)) gtk_widget_grab_default (widget); break; case PROP_RECEIVES_DEFAULT: - if (g_value_get_boolean (value)) - GTK_WIDGET_SET_FLAGS (widget, GTK_RECEIVES_DEFAULT); - else - GTK_WIDGET_UNSET_FLAGS (widget, GTK_RECEIVES_DEFAULT); + gtk_widget_set_receives_default (widget, g_value_get_boolean (value)); break; case PROP_STYLE: gtk_widget_set_style (widget, g_value_get_object (value)); @@ -2523,6 +2520,9 @@ gtk_widget_set_property (GObject *object, if (GTK_WIDGET_VISIBLE (widget)) gtk_widget_queue_tooltip_query (widget); break; + case PROP_DOUBLE_BUFFERED: + gtk_widget_set_double_buffered (widget, g_value_get_boolean (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -2630,6 +2630,9 @@ gtk_widget_get_property (GObject *object, case PROP_WINDOW: g_value_set_object (value, gtk_widget_get_window (widget)); break; + case PROP_DOUBLE_BUFFERED: + g_value_set_boolean (value, gtk_widget_get_double_buffered (widget)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -5066,8 +5069,10 @@ _gtk_widget_grab_notify (GtkWidget *widget, * * Causes @widget to have the keyboard focus for the #GtkWindow it's * inside. @widget must be a focusable widget, such as a #GtkEntry; - * something like #GtkFrame won't work. (More precisely, it must have the - * %GTK_CAN_FOCUS flag set.) + * something like #GtkFrame won't work. + * + * More precisely, it must have the %GTK_CAN_FOCUS flag set. Use + * gtk_widget_set_can_focus() to modify that flag. **/ void gtk_widget_grab_focus (GtkWidget *widget) @@ -5258,6 +5263,74 @@ gtk_widget_real_keynav_failed (GtkWidget *widget, return TRUE; } +/** + * gtk_widget_set_can_focus: + * @widget: a #GtkWidget + * @can_focus: whether or not @widget can own the input focus. + * + * Specifies whether @widget can own the input focus. See + * gtk_widget_grab_focus() for actually setting the input focus on a + * widget. + * + * Since: 2.18 + **/ +void +gtk_widget_set_can_focus (GtkWidget *widget, + gboolean can_focus) +{ + g_return_if_fail (GTK_IS_WIDGET (widget)); + + if (can_focus != GTK_WIDGET_CAN_FOCUS (widget)) + { + if (can_focus) + GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS); + else + GTK_WIDGET_UNSET_FLAGS (widget, GTK_CAN_FOCUS); + + gtk_widget_queue_resize (widget); + g_object_notify (G_OBJECT (widget), "can-focus"); + } +} + +/** + * gtk_widget_get_can_focus: + * @widget: a #GtkWidget + * + * Determines whether @widget can own the input focus. See + * gtk_widget_set_can_focus(). + * + * Return value: %TRUE if @widget can own the input focus, %FALSE otherwise + * + * Since: 2.18 + **/ +gboolean +gtk_widget_get_can_focus (GtkWidget *widget) +{ + g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE); + + return GTK_WIDGET_CAN_FOCUS (widget); +} + +/** + * gtk_widget_has_focus: + * @widget: a #GtkWidget + * + * Determines if the widget has the global input focus. See + * gtk_widget_is_focus() for the difference between having the global + * input focus, and only having the focus within a toplevel. + * + * Return value: %TRUE if the widget has the global input focus. + * + * Since: 2.18 + **/ +gboolean +gtk_widget_has_focus (GtkWidget *widget) +{ + g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE); + + return GTK_WIDGET_HAS_FOCUS (widget); +} + /** * gtk_widget_is_focus: * @widget: a #GtkWidget @@ -5284,14 +5357,82 @@ gtk_widget_is_focus (GtkWidget *widget) return FALSE; } +/** + * gtk_widget_set_can_default: + * @widget: a #GtkWidget + * @can_default: whether or not @widget can be a default widget. + * + * Specifies whether @widget can be a default widget. See + * gtk_widget_grab_default() for details about the meaning of + * "default". + * + * Since: 2.18 + **/ +void +gtk_widget_set_can_default (GtkWidget *widget, + gboolean can_default) +{ + g_return_if_fail (GTK_IS_WIDGET (widget)); + + if (can_default != GTK_WIDGET_CAN_DEFAULT (widget)) + { + if (can_default) + GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_DEFAULT); + else + GTK_WIDGET_UNSET_FLAGS (widget, GTK_CAN_DEFAULT); + + gtk_widget_queue_resize (widget); + g_object_notify (G_OBJECT (widget), "can-default"); + } +} + +/** + * gtk_widget_get_can_default: + * @widget: a #GtkWidget + * + * Determines whether @widget can be a default widget. See + * gtk_widget_set_can_default(). + * + * Return value: %TRUE if @widget can be a default widget, %FALSE otherwise + * + * Since: 2.18 + **/ +gboolean +gtk_widget_get_can_default (GtkWidget *widget) +{ + g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE); + + return GTK_WIDGET_CAN_DEFAULT (widget); +} + +/** + * gtk_widget_has_default: + * @widget: a #GtkWidget + * + * Determines whether @widget is the current default widget within its + * toplevel. See gtk_widget_set_can_default(). + * + * Return value: %TRUE if @widget is the current default widget within + * its toplevel, %FALSE otherwise + * + * Since: 2.18 + */ +gboolean +gtk_widget_has_default (GtkWidget *widget) +{ + g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE); + + return GTK_WIDGET_HAS_DEFAULT (widget); +} + /** * gtk_widget_grab_default: * @widget: a #GtkWidget * * Causes @widget to become the default widget. @widget must have the * %GTK_CAN_DEFAULT flag set; typically you have to set this flag - * yourself by calling GTK_WIDGET_SET_FLAGS (@widget, - * GTK_CAN_DEFAULT). The default widget is activated when + * yourself by calling gtk_widget_set_can_default (@widget, + * %TRUE). The default widget is activated when * the user presses Enter in a window. Default widgets must be * activatable, that is, gtk_widget_activate() should affect them. **/ @@ -5311,6 +5452,81 @@ gtk_widget_grab_default (GtkWidget *widget) g_warning (G_STRLOC ": widget not within a GtkWindow"); } +/** + * gtk_widget_set_receives_default: + * @widget: a #GtkWidget + * @receives_default: whether or not @widget can be a default widget. + * + * Specifies whether @widget will be treated as the default widget + * within its toplevel when it has the focus, even if another widget + * is the default. + * + * See gtk_widget_grab_default() for details about the meaning of + * "default". + * + * Since: 2.18 + **/ +void +gtk_widget_set_receives_default (GtkWidget *widget, + gboolean receives_default) +{ + g_return_if_fail (GTK_IS_WIDGET (widget)); + + if (receives_default != gtk_widget_get_receives_default (widget)) + { + if (receives_default) + GTK_WIDGET_SET_FLAGS (widget, GTK_RECEIVES_DEFAULT); + else + GTK_WIDGET_UNSET_FLAGS (widget, GTK_RECEIVES_DEFAULT); + + g_object_notify (G_OBJECT (widget), "receives-default"); + } +} + +/** + * gtk_widget_get_receives_default: + * @widget: a #GtkWidget + * + * Determines whether @widget is alyways treated as default widget + * withing its toplevel when it has the focus, even if another widget + * is the default. + * + * See gtk_widget_set_receives_default(). + * + * Return value: %TRUE if @widget acts as default widget when focussed, + * %FALSE otherwise + * + * Since: 2.18 + **/ +gboolean +gtk_widget_get_receives_default (GtkWidget *widget) +{ + g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE); + + return (GTK_WIDGET_FLAGS (widget) & GTK_RECEIVES_DEFAULT) != 0; +} + +/** + * gtk_widget_has_grab: + * @widget: a #GtkWidget + * + * Determines whether the widget is currently grabbing events, so it + * is the only widget receiving input events (keyboard and mouse). + * + * See also gtk_grab_add(). + * + * Return value: %TRUE if the widget is in the grab_widgets stack + * + * Since: 2.18 + **/ +gboolean +gtk_widget_has_grab (GtkWidget *widget) +{ + g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE); + + return (GTK_WIDGET_FLAGS (widget) & GTK_HAS_GRAB) != 0; +} + /** * gtk_widget_set_name: * @widget: a #GtkWidget @@ -5401,6 +5617,164 @@ gtk_widget_set_state (GtkWidget *widget, } } +/** + * gtk_widget_get_state: + * @widget: a #GtkWidget + * + * Returns the widget's state. See gtk_widget_set_state(). + * + * Returns: the state of @widget. + * + * Since: 2.18 + */ +GtkStateType +gtk_widget_get_state (GtkWidget *widget) +{ + g_return_val_if_fail (GTK_IS_WIDGET (widget), GTK_STATE_NORMAL); + + return widget->state; +} + +/** + * gtk_widget_set_visible: + * @widget: a #GtkWidget + * @visible: whether the widget should be shown or not + * + * Sets the visibility state of @widget. Note that setting this to + * %TRUE doesn't mean the widget is actually viewable, see + * gtk_widget_get_visible(). + * + * This function simply calls gtk_widget_show() or gtk_widget_hide() + * but is nicer to use when the visibility of the widget depends on + * some condition. + * + * Since: 2.18 + **/ +void +gtk_widget_set_visible (GtkWidget *widget, + gboolean visible) +{ + g_return_if_fail (GTK_IS_WIDGET (widget)); + + if (visible != GTK_WIDGET_VISIBLE (widget)) + { + if (visible) + gtk_widget_show (widget); + else + gtk_widget_hide (widget); + } +} + +/** + * gtk_widget_get_visible: + * @widget: a #GtkWidget + * + * Determines whether the widget is visible. Note that this doesn't + * take into account whether the widget's parent is also visible + * or the widget is obscured in any way. + * + * See gtk_widget_set_visible(). + * + * Return value: %TRUE if the widget is visible + * + * Since: 2.18 + **/ +gboolean +gtk_widget_get_visible (GtkWidget *widget) +{ + g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE); + + return (GTK_WIDGET_FLAGS (widget) & GTK_VISIBLE) != 0; +} + +/** + * gtk_widget_set_has_window: + * @widget: a #GtkWidget + * @has_window: whether or not @widget has a window. + * + * Specifies whether @widget has a #GdkWindow of its own. Note that + * all realized widgets have a non-%NULL "window" pointer + * (gtk_widget_get_window() never returns a %NULL window when a widget + * is realized), but for many of them it's actually the #GdkWindow of + * one of its parent widgets. Widgets that create a %window for + * themselves in GtkWidget::realize() however must announce this by + * calling this function with @has_window = %TRUE. + * + * This function should only be called by widget implementations, + * and they should call it in their init() function. + * + * Since: 2.18 + **/ +void +gtk_widget_set_has_window (GtkWidget *widget, + gboolean has_window) +{ + g_return_if_fail (GTK_IS_WIDGET (widget)); + + if (has_window) + GTK_WIDGET_UNSET_FLAGS (widget, GTK_NO_WINDOW); + else + GTK_WIDGET_SET_FLAGS (widget, GTK_NO_WINDOW); +} + +/** + * gtk_widget_get_has_window: + * @widget: a #GtkWidget + * + * Determines whether @widget has a #GdkWindow of its own. See + * gtk_widget_set_has_window(). + * + * Return value: %TRUE if @widget has a window, %FALSE otherwise + * + * Since: 2.18 + **/ +gboolean +gtk_widget_get_has_window (GtkWidget *widget) +{ + g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE); + + return !GTK_WIDGET_NO_WINDOW (widget); +} + +/** + * gtk_widget_is_toplevel: + * @widget: a #GtkWidget + * + * Determines whether @widget is a toplevel widget. Currently only + * #GtkWindow and #GtkInvisible are toplevel widgets. Toplevel + * widgets have no parent widget. + * + * Return value: %TRUE if @widget is a toplevel, %FALSE otherwise + * + * Since: 2.18 + **/ +gboolean +gtk_widget_is_toplevel (GtkWidget *widget) +{ + g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE); + + return (GTK_WIDGET_FLAGS (widget) & GTK_TOPLEVEL) != 0; +} + +/** + * gtk_widget_is_drawable: + * @widget: a #GtkWidget + * + * Determines whether @widget can be drawn to. A widget can be drawn + * to if it is mapped and visible. + * + * Return value: %TRUE if @widget is drawable, %FALSE otherwise + * + * Since: 2.18 + **/ +gboolean +gtk_widget_is_drawable (GtkWidget *widget) +{ + g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE); + + return ((GTK_WIDGET_FLAGS (widget) & GTK_VISIBLE) != 0 && + (GTK_WIDGET_FLAGS (widget) & GTK_MAPPED) != 0); +} /** * gtk_widget_set_app_paintable: @@ -5448,6 +5822,27 @@ gtk_widget_set_app_paintable (GtkWidget *widget, } } +/** + * gtk_widget_get_app_paintable: + * @widget: a #GtkWidget + * + * Determines whether the application intends to draw on the widget in + * an #GtkWidget::expose-event handler. + * + * See gtk_widget_set_app_paintable() + * + * Return value: %TRUE if the widget is app paintable + * + * Since: 2.18 + **/ +gboolean +gtk_widget_get_app_paintable (GtkWidget *widget) +{ + g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE); + + return (GTK_WIDGET_FLAGS (widget) & GTK_APP_PAINTABLE) != 0; +} + /** * gtk_widget_set_double_buffered: * @widget: a #GtkWidget @@ -5478,10 +5873,35 @@ gtk_widget_set_double_buffered (GtkWidget *widget, { g_return_if_fail (GTK_IS_WIDGET (widget)); - if (double_buffered) - GTK_WIDGET_SET_FLAGS (widget, GTK_DOUBLE_BUFFERED); - else - GTK_WIDGET_UNSET_FLAGS (widget, GTK_DOUBLE_BUFFERED); + if (double_buffered != GTK_WIDGET_DOUBLE_BUFFERED (widget)) + { + if (double_buffered) + GTK_WIDGET_SET_FLAGS (widget, GTK_DOUBLE_BUFFERED); + else + GTK_WIDGET_UNSET_FLAGS (widget, GTK_DOUBLE_BUFFERED); + + g_object_notify (G_OBJECT (widget), "double-buffered"); + } +} + +/** + * gtk_widget_get_double_buffered: + * @widget: a #GtkWidget + * + * Determines whether the widget is double buffered. + * + * See gtk_widget_set_double_buffered() + * + * Return value: %TRUE if the widget is double buffered + * + * Since: 2.18 + **/ +gboolean +gtk_widget_get_double_buffered (GtkWidget *widget) +{ + g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE); + + return (GTK_WIDGET_FLAGS (widget) & GTK_DOUBLE_BUFFERED) != 0; } /** @@ -5566,6 +5986,47 @@ gtk_widget_set_sensitive (GtkWidget *widget, g_object_notify (G_OBJECT (widget), "sensitive"); } +/** + * gtk_widget_get_sensitive: + * @widget: a #GtkWidget + * + * Returns the widget's sensitivity (in the sense of returning + * the value that has been set using gtk_widget_set_sensitive()). + * + * The effective sensitivity of a widget is however determined by both its + * own and its parent widget's sensitivity. See gtk_widget_is_sensitive(). + * + * Returns: %TRUE if the widget is sensitive + * + * Since: 2.18 + */ +gboolean +gtk_widget_get_sensitive (GtkWidget *widget) +{ + g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE); + + return GTK_WIDGET_SENSITIVE (widget); +} + +/** + * gtk_widget_is_sensitive: + * @widget: a #GtkWidget + * + * Returns the widget's effective sensitivity, which means + * it is sensitive itself and also its parent widget is sensntive + * + * Returns: %TRUE if the widget is effectively sensitive + * + * Since: 2.18 + */ +gboolean +gtk_widget_is_sensitive (GtkWidget *widget) +{ + g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE); + + return GTK_WIDGET_IS_SENSITIVE (widget); +} + /** * gtk_widget_set_parent: * @widget: a #GtkWidget @@ -10142,6 +10603,9 @@ gtk_widget_real_set_has_tooltip (GtkWidget *widget, * the default tooltip window. If @custom_window is %NULL, the default * tooltip window will be used. * + * If the custom window should have the default theming it needs to + * have the name "gtk-tooltip", see gtk_widget_set_name(). + * * Since: 2.12 */ void @@ -10370,6 +10834,76 @@ gtk_widget_get_has_tooltip (GtkWidget *widget) return has_tooltip; } +/** + * gtk_widget_get_allocation: + * @widget: a #GtkWidget + * @allocation: a pointer to a #GtkAllocation to copy to + * + * Retrieves the widget's allocation. + * + * Since: 2.18 + */ +void +gtk_widget_get_allocation (GtkWidget *widget, + GtkAllocation *allocation) +{ + g_return_if_fail (GTK_IS_WIDGET (widget)); + g_return_if_fail (allocation != NULL); + + *allocation = widget->allocation; +} + +/** + * gtk_widget_set_allocation: + * @widget: a #GtkWidget + * @allocation: a pointer to a #GtkAllocation to copy from + * + * Sets the widget's allocation. This should not be used + * directly, but from within a widget's size_allocate method. + * + * Since: 2.18 + */ +void +gtk_widget_set_allocation (GtkWidget *widget, + const GtkAllocation *allocation) +{ + g_return_if_fail (GTK_IS_WIDGET (widget)); + g_return_if_fail (allocation != NULL); + + widget->allocation = *allocation; +} + +/** + * gtk_widget_set_window: + * @widget: a #GtkWidget + * @window: a #GdkWindow + * + * Sets a widget's window. This function should only be used in a + * widget's GtkWidget::realize() implementation. The %window passed is + * usually either new window created with gdk_window_new(), or the + * window of its parent widget as returned by + * gtk_widget_get_parent_window(). + * + * Widgets must indicate whether they will create their own #GdkWindow + * by calling gtk_widget_set_has_window(). This is usually done in the + * widget's init() function. + * + * Since: 2.18 + */ +void +gtk_widget_set_window (GtkWidget *widget, + GdkWindow *window) +{ + g_return_if_fail (GTK_IS_WIDGET (widget)); + g_return_if_fail (window == NULL || GDK_IS_WINDOW (window)); + + if (widget->window != window) + { + widget->window = window; + g_object_notify (G_OBJECT (widget), "window"); + } +} + /** * gtk_widget_get_window: * @widget: a #GtkWidget diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h index 2d89fb0e29..c1488754fb 100644 --- a/gtk/gtkwidget.h +++ b/gtk/gtkwidget.h @@ -548,33 +548,80 @@ void gtk_widget_child_notify (GtkWidget *widget, const gchar *child_property); void gtk_widget_thaw_child_notify (GtkWidget *widget); +void gtk_widget_set_can_focus (GtkWidget *widget, + gboolean can_focus); +gboolean gtk_widget_get_can_focus (GtkWidget *widget); +gboolean gtk_widget_has_focus (GtkWidget *widget); gboolean gtk_widget_is_focus (GtkWidget *widget); -void gtk_widget_grab_focus (GtkWidget *widget); -void gtk_widget_grab_default (GtkWidget *widget); +void gtk_widget_grab_focus (GtkWidget *widget); + +void gtk_widget_set_can_default (GtkWidget *widget, + gboolean can_default); +gboolean gtk_widget_get_can_default (GtkWidget *widget); +gboolean gtk_widget_has_default (GtkWidget *widget); +void gtk_widget_grab_default (GtkWidget *widget); + +void gtk_widget_set_receives_default (GtkWidget *widget, + gboolean receives_default); +gboolean gtk_widget_get_receives_default (GtkWidget *widget); + +gboolean gtk_widget_has_grab (GtkWidget *widget); void gtk_widget_set_name (GtkWidget *widget, const gchar *name); G_CONST_RETURN gchar* gtk_widget_get_name (GtkWidget *widget); + void gtk_widget_set_state (GtkWidget *widget, GtkStateType state); +GtkStateType gtk_widget_get_state (GtkWidget *widget); + void gtk_widget_set_sensitive (GtkWidget *widget, gboolean sensitive); +gboolean gtk_widget_get_sensitive (GtkWidget *widget); +gboolean gtk_widget_is_sensitive (GtkWidget *widget); + +void gtk_widget_set_visible (GtkWidget *widget, + gboolean visible); +gboolean gtk_widget_get_visible (GtkWidget *widget); + +void gtk_widget_set_has_window (GtkWidget *widget, + gboolean has_window); +gboolean gtk_widget_get_has_window (GtkWidget *widget); + +gboolean gtk_widget_is_toplevel (GtkWidget *widget); +gboolean gtk_widget_is_drawable (GtkWidget *widget); + void gtk_widget_set_app_paintable (GtkWidget *widget, gboolean app_paintable); +gboolean gtk_widget_get_app_paintable (GtkWidget *widget); + void gtk_widget_set_double_buffered (GtkWidget *widget, gboolean double_buffered); +gboolean gtk_widget_get_double_buffered (GtkWidget *widget); + void gtk_widget_set_redraw_on_allocate (GtkWidget *widget, gboolean redraw_on_allocate); + void gtk_widget_set_parent (GtkWidget *widget, GtkWidget *parent); GtkWidget * gtk_widget_get_parent (GtkWidget *widget); + void gtk_widget_set_parent_window (GtkWidget *widget, GdkWindow *parent_window); GdkWindow * gtk_widget_get_parent_window (GtkWidget *widget); + void gtk_widget_set_child_visible (GtkWidget *widget, gboolean is_visible); gboolean gtk_widget_get_child_visible (GtkWidget *widget); -GdkWindow* gtk_widget_get_window (GtkWidget *widget); + +void gtk_widget_set_window (GtkWidget *widget, + GdkWindow *window); +GdkWindow * gtk_widget_get_window (GtkWidget *widget); + +void gtk_widget_get_allocation (GtkWidget *widget, + GtkAllocation *allocation); +void gtk_widget_set_allocation (GtkWidget *widget, + const GtkAllocation *allocation); gboolean gtk_widget_child_focus (GtkWidget *widget, GtkDirectionType direction); diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index 1238c2295c..c0815a9322 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -496,7 +496,7 @@ gtk_window_class_init (GtkWindowClass *klass) P_("Unique identifier for the window to be used when restoring a session"), NULL, GTK_PARAM_READWRITE)); - + /** * GtkWindow:startup-id: * @@ -505,9 +505,9 @@ gtk_window_class_init (GtkWindowClass *klass) * for more details. * * Since: 2.12 - */ + */ g_object_class_install_property (gobject_class, - PROP_ROLE, + PROP_STARTUP_ID, g_param_spec_string ("startup-id", P_("Startup ID"), P_("Unique startup identifier for the window used by startup-notification"), @@ -4400,6 +4400,7 @@ static void gtk_window_finalize (GObject *object) { GtkWindow *window = GTK_WINDOW (object); + GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window); GtkMnemonicHash *mnemonic_hash; g_free (window->title); @@ -4427,11 +4428,11 @@ gtk_window_finalize (GObject *object) } if (window->screen) - { - g_signal_handlers_disconnect_by_func (window->screen, - gtk_window_on_composited_changed, window); - } - + g_signal_handlers_disconnect_by_func (window->screen, + gtk_window_on_composited_changed, window); + + g_free (priv->startup_id); + G_OBJECT_CLASS (gtk_window_parent_class)->finalize (object); } @@ -4601,7 +4602,8 @@ gtk_window_map (GtkWidget *widget) /* Make sure we have a "real" id */ if (!startup_id_is_fake (priv->startup_id)) gdk_notify_startup_complete_with_id (priv->startup_id); - + + g_free (priv->startup_id); priv->startup_id = NULL; } else if (!sent_startup_notification) @@ -8319,7 +8321,7 @@ _gtk_window_set_is_active (GtkWindow *window, } /** - * _gtk_windwo_set_is_toplevel: + * _gtk_window_set_is_toplevel: * @window: a #GtkWindow * @is_toplevel: %TRUE if the window is still a real toplevel (nominally a * parent of the root window); %FALSE if it is not (for example, for an diff --git a/gtk/makefile.msc.in b/gtk/makefile.msc.in index 83aa1b8657..bb6ac9999e 100644 --- a/gtk/makefile.msc.in +++ b/gtk/makefile.msc.in @@ -55,6 +55,12 @@ gtkbuiltincache.h: gtk-update-icon-cache.exe copy gtk-media-next-ltr.png gtk-media-previous-rtl.png copy gtk-media-forward-ltr.png gtk-media-rewind-rtl.png copy gtk-floppy.png gtk-save.png + copy gtk-harddisk.png drive-harddisk.png + copy gtk-directory.png folder.png + copy gtk-directory.png folder-remote.png + copy gtk-home.png user-home.png + copy gtk-directory.png user-desktop.png + copy gtk-file.png text-x-generic.png cd ..\24 copy gtk-go-forward-ltr.png gtk-go-back-rtl.png copy gtk-go-back-ltr.png gtk-go-forward-rtl.png @@ -65,6 +71,12 @@ gtkbuiltincache.h: gtk-update-icon-cache.exe copy gtk-media-next-ltr.png gtk-media-previous-rtl.png copy gtk-media-forward-ltr.png gtk-media-rewind-rtl.png copy gtk-floppy.png gtk-save.png + copy gtk-harddisk.png drive-harddisk.png + copy gtk-directory.png folder.png + copy gtk-directory.png folder-remote.png + copy gtk-home.png user-home.png + copy gtk-directory.png user-desktop.png + copy gtk-file.png text-x-generic.png cd ..\.. del gtkicontheme.obj gtk-update-icon-cache --force --ignore-theme-index \ @@ -101,6 +113,7 @@ gtk_OBJECTS_deprecated = \ gtklistitem.obj \ gtkprogress.obj \ gtktipsquery.obj \ + gtkshow.obj \ gtksignal.obj \ gtkpixmap.obj \ gtkpreview.obj \ @@ -144,7 +157,6 @@ gtk_OBJECTS_file = \ gtkfilefilter.obj \ gtkfilesystem.obj \ gtkfilesystemmodel.obj \ - gtkfilesystemwin32.obj \ gtk_OBJECTS_print = \ gtkprint-win32.obj \ @@ -193,6 +205,7 @@ gtk_OBJECTS = \ gtkaccessible.obj \ gtkaction.obj \ gtkactiongroup.obj \ + gtkactivatable.obj \ gtkadjustment.obj \ gtkalignment.obj \ gtkarrow.obj \ @@ -222,6 +235,7 @@ gtk_OBJECTS = \ gtkdrawingarea.obj \ gtkeditable.obj \ gtkentry.obj \ + gtkentrybuffer.obj \ gtkentrycompletion.obj \ gtkeventbox.obj \ gtkexpander.obj \ @@ -251,6 +265,7 @@ gtk_OBJECTS = \ gtkimcontextsimple.obj \ gtkimmodule.obj \ gtkimmulticontext.obj \ + gtkinfobar.obj \ gtkinputdialog.obj \ gtkinvisible.obj \ gtkitem.obj \ @@ -271,8 +286,10 @@ gtk_OBJECTS = \ gtkmnemonichash.obj \ gtkmodules.obj \ gtkmountoperation.obj \ + gtkmountoperation-stub.obj \ gtknotebook.obj \ gtkobject.obj \ + gtkorientable.obj \ gtkpagesetup.obj \ gtkpaned.obj \ gtkpapersize.obj \ @@ -347,6 +364,7 @@ gtk_public_h_sources = \ gtkaccessible.h \ gtkaction.h \ gtkactiongroup.h \ + gtkactivatable.h \ gtkadjustment.h \ gtkalignment.h \ gtkarrow.h \ @@ -390,6 +408,7 @@ gtk_public_h_sources = \ gtkdrawingarea.h \ gtkeditable.h \ gtkentry.h \ + gtkentrybuffer.h \ gtkentrycompletion.h \ gtkenums.h \ gtkeventbox.h \ @@ -553,10 +572,10 @@ gtk.def: gtk.symbols makefile.msc -DG_GNUC_PRINTF=;G_GNUC_PRINTF gtk.symbols >> gtk.def gtkalias.h: gtk.symbols - cl /EP -DG_OS_WIN32 -DGTK_WINDOWING_WIN32 -DINCLUDE_INTERNAL_SYMBOLS gtk.symbols | $(PERL) makegtkalias.pl > gtkalias.h + $(PERL) makegtkalias.pl < gtk.symbols > gtkalias.h gtkaliasdef.c: gtk.symbols - perl makegtkalias.pl -def < gtk.symbols > gtkaliasdef.c + $(PERL) makegtkalias.pl -def < gtk.symbols > gtkaliasdef.c # generate type identifier header (GTK_TYPE_WIDGET_FLAGS) # use 'echo' to work around 'command line too long' diff --git a/gtk/tests/Makefile.am b/gtk/tests/Makefile.am index 4c8ff1f1a6..c287c258df 100644 --- a/gtk/tests/Makefile.am +++ b/gtk/tests/Makefile.am @@ -34,6 +34,10 @@ TEST_PROGS += treestore treestore_SOURCES = treestore.c treestore_LDADD = $(progs_ldadd) +TEST_PROGS += treeview +treeview_SOURCES = treeview.c +treeview_LDADD = $(progs_ldadd) + TEST_PROGS += treeview-scrolling treeview_scrolling_SOURCES = treeview-scrolling.c treeview_scrolling_LDADD = $(progs_ldadd) @@ -78,4 +82,12 @@ TEST_PROGS += textbuffer textbuffer_SOURCES = textbuffer.c pixbuf-init.c textbuffer_LDADD = $(progs_ldadd) +TEST_PROGS += filtermodel +filtermodel_SOURCES = filtermodel.c +filtermodel_LDADD = $(progs_ldadd) + +TEST_PROGS += expander +expander_SOURCES = expander.c +expander_LDADD = $(progs_ldadd) + -include $(top_srcdir)/git.mk diff --git a/gtk/tests/builder.c b/gtk/tests/builder.c index f5a85ac4fa..2ae604d5e6 100644 --- a/gtk/tests/builder.c +++ b/gtk/tests/builder.c @@ -116,6 +116,13 @@ test_parser (void) GTK_BUILDER_ERROR_INVALID_VALUE)); g_error_free (error); + error = NULL; + gtk_builder_add_from_string (builder, "", -1, &error); + g_assert (g_error_matches (error, + GTK_BUILDER_ERROR, + GTK_BUILDER_ERROR_DUPLICATE_ID)); + g_error_free (error); + g_object_unref (builder); } @@ -1944,6 +1951,8 @@ test_icon_factory (void) gtk_icon_factory_add_default (GTK_ICON_FACTORY (factory)); image = gtk_image_new_from_stock ("apple-red", GTK_ICON_SIZE_BUTTON); g_assert (image != NULL); + g_object_ref_sink (image); + g_object_unref (image); g_object_unref (builder); @@ -2129,6 +2138,7 @@ test_requires (void) GTK_BUILDER_ERROR_VERSION_MISMATCH)); g_object_unref (builder); g_error_free (error); + g_free (buffer); } static void @@ -2172,7 +2182,7 @@ test_add_objects (void) " " " " " " - " " + " " " second label" " " " " diff --git a/gtk/tests/defaultvalue.c b/gtk/tests/defaultvalue.c index 8451490948..a3534b176d 100644 --- a/gtk/tests/defaultvalue.c +++ b/gtk/tests/defaultvalue.c @@ -102,6 +102,9 @@ test_type (gconstpointer data) { GdkWindowAttr attributes; attributes.window_type = GDK_WINDOW_TEMP; + attributes.event_mask = 0; + attributes.width = 100; + attributes.height = 100; instance = g_object_ref (gdk_window_new (NULL, &attributes, 0)); } else @@ -170,7 +173,8 @@ test_type (gconstpointer data) /* Default invisible char is determined at runtime */ if (g_type_is_a (type, GTK_TYPE_ENTRY) && - strcmp (pspec->name, "invisible-char") == 0) + (strcmp (pspec->name, "invisible-char") == 0 || + strcmp (pspec->name, "buffer") == 0)) continue; /* Gets set to the cwd */ @@ -235,7 +239,10 @@ test_type (gconstpointer data) strcmp (pspec->name, "gtk-icon-theme-name") == 0 || strcmp (pspec->name, "gtk-im-module") == 0 || strcmp (pspec->name, "gtk-key-theme-name") == 0 || - strcmp (pspec->name, "gtk-theme-name") == 0)) + strcmp (pspec->name, "gtk-theme-name") == 0 || + strcmp (pspec->name, "gtk-sound-theme-name") == 0 || + strcmp (pspec->name, "gtk-enable-input-feedback-sounds") == 0 || + strcmp (pspec->name, "gtk-enable-event-sounds") == 0)) continue; if (g_type_is_a (type, GTK_TYPE_SPIN_BUTTON) && diff --git a/gtk/tests/expander.c b/gtk/tests/expander.c new file mode 100644 index 0000000000..853b20aada --- /dev/null +++ b/gtk/tests/expander.c @@ -0,0 +1,94 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GTK+ Team and others 1997-2001. See the AUTHORS + * file for a list of people on the GTK+ Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. + */ +#include + +static void +test_click_expander (void) +{ + GtkWidget *window = gtk_test_create_simple_window ("Test Window", "Test click on expander"); + GtkWidget *expander = gtk_expander_new ("Test Expander"); + GtkWidget *label = gtk_label_new ("Test Label"); + gboolean expanded; + gboolean simsuccess; + gtk_container_add (GTK_CONTAINER (expander), label); + gtk_container_add (GTK_CONTAINER (GTK_BIN (window)->child), expander); + gtk_widget_show (expander); + gtk_widget_show (label); + gtk_widget_show_now (window); + /* check initial expander state */ + expanded = gtk_expander_get_expanded (GTK_EXPANDER (expander)); + g_assert (!expanded); + /* check expanding */ + simsuccess = gtk_test_widget_click (expander, 1, 0); + g_assert (simsuccess == TRUE); + while (gtk_events_pending ()) /* let expander timeout/idle handlers update */ + gtk_main_iteration (); + expanded = gtk_expander_get_expanded (GTK_EXPANDER (expander)); + g_assert (expanded); + /* check collapsing */ + simsuccess = gtk_test_widget_click (expander, 1, 0); + g_assert (simsuccess == TRUE); + while (gtk_events_pending ()) /* let expander timeout/idle handlers update */ + gtk_main_iteration (); + expanded = gtk_expander_get_expanded (GTK_EXPANDER (expander)); + g_assert (!expanded); +} + +static void +test_click_content_widget (void) +{ + GtkWidget *window = gtk_test_create_simple_window ("Test Window", "Test click on content widget"); + GtkWidget *expander = gtk_expander_new ("Test Expander"); + GtkWidget *entry = gtk_entry_new (); + gboolean expanded; + gboolean simsuccess; + gtk_container_add (GTK_CONTAINER (expander), entry); + gtk_container_add (GTK_CONTAINER (GTK_BIN (window)->child), expander); + gtk_expander_set_expanded (GTK_EXPANDER (expander), TRUE); + gtk_widget_show (expander); + gtk_widget_show (entry); + gtk_widget_show_now (window); + + /* check click on content with expander open */ + expanded = gtk_expander_get_expanded (GTK_EXPANDER (expander)); + g_assert (expanded); + simsuccess = gtk_test_widget_click (entry, 1, 0); + g_assert (simsuccess == TRUE); + while (gtk_events_pending ()) /* let expander timeout/idle handlers update */ + gtk_main_iteration (); + expanded = gtk_expander_get_expanded (GTK_EXPANDER (expander)); + g_assert (expanded); +} + +int +main (int argc, + char *argv[]) +{ + gtk_test_init (&argc, &argv); + g_test_add_func ("/expander/click-expander", test_click_expander); + g_test_add_func ("/expander/click-content-widget", test_click_content_widget); + return g_test_run(); +} diff --git a/gtk/tests/filtermodel.c b/gtk/tests/filtermodel.c new file mode 100644 index 0000000000..eebd382038 --- /dev/null +++ b/gtk/tests/filtermodel.c @@ -0,0 +1,3001 @@ +/* Extensive GtkTreeModelFilter tests. + * Copyright (C) 2009 Kristian Rietveld + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include + + +/* Left to do: + * - Proper coverage checking to see if the unit tests cover + * all possible cases. + * - Verify if the ref counting is done properly for both the + * normal ref_count and the zero_ref_count. One way to test + * this area is by collapsing/expanding branches on the view + * that is connected to the filter model. + * - Check if the iterator stamp is incremented at the correct times. + */ + + +/* + * Model creation + */ + +#define LEVEL_LENGTH 5 + +static void +create_tree_store_set_values (GtkTreeStore *store, + GtkTreeIter *iter, + gboolean visible) +{ + GtkTreePath *path; + gchar *path_string; + + path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), iter); + path_string = gtk_tree_path_to_string (path); + + gtk_tree_store_set (store, iter, + 0, path_string, + 1, visible, + -1); + + gtk_tree_path_free (path); + g_free (path_string); +} + +static void +create_tree_store_recurse (int depth, + GtkTreeStore *store, + GtkTreeIter *parent, + gboolean visible) +{ + int i; + + for (i = 0; i < LEVEL_LENGTH; i++) + { + GtkTreeIter iter; + + gtk_tree_store_insert (store, &iter, parent, i); + create_tree_store_set_values (store, &iter, visible); + + if (depth > 0) + create_tree_store_recurse (depth - 1, store, &iter, visible); + } +} + +static GtkTreeStore * +create_tree_store (int depth, + gboolean visible) +{ + GtkTreeStore *store; + + store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN); + + create_tree_store_recurse (depth, store, NULL, visible); + + return store; +} + +/* + * Signal monitor + */ + +typedef enum +{ + ROW_INSERTED, + ROW_DELETED, + ROW_CHANGED, + ROW_HAS_CHILD_TOGGLED, + ROWS_REORDERED, + LAST_SIGNAL +} +SignalName; + +static const char * +signal_name_to_string (SignalName signal) +{ + switch (signal) + { + case ROW_INSERTED: + return "row-inserted"; + + case ROW_DELETED: + return "row-deleted"; + + case ROW_CHANGED: + return "row-changed"; + + case ROW_HAS_CHILD_TOGGLED: + return "row-has-child-toggled"; + + case ROWS_REORDERED: + return "rows-reordered"; + + default: + /* Fall through */ + break; + } + + return "(unknown)"; +} + +typedef struct +{ + SignalName signal; + GtkTreePath *path; +} +Signal; + + +static Signal * +signal_new (SignalName signal, GtkTreePath *path) +{ + Signal *s; + + s = g_new0 (Signal, 1); + s->signal = signal; + s->path = gtk_tree_path_copy (path); + + return s; +} + +static void +signal_free (Signal *s) +{ + if (s->path) + gtk_tree_path_free (s->path); + + g_free (s); +} + + +typedef struct +{ + GQueue *queue; + GtkTreeModel *client; + guint signal_ids[LAST_SIGNAL]; +} +SignalMonitor; + + +static void +signal_monitor_generic_handler (SignalMonitor *m, + SignalName signal, + GtkTreeModel *model, + GtkTreePath *path) +{ + Signal *s; + + if (g_queue_is_empty (m->queue)) + { + g_error ("Signal queue empty\n"); + g_assert_not_reached (); + } + + if (m->client != model) + { + g_error ("Model mismatch; expected %p, got %p\n", + m->client, model); + g_assert_not_reached (); + } + + s = g_queue_peek_tail (m->queue); + +#if 0 + /* For debugging: output signals that are coming in. Leaks memory. */ + g_print ("signal=%d path=%s\n", signal, gtk_tree_path_to_string (path)); +#endif + + if (s->signal != signal + || gtk_tree_path_compare (s->path, path) != 0) + { + gchar *path_str, *s_path_str; + + s_path_str = gtk_tree_path_to_string (s->path); + path_str = gtk_tree_path_to_string (path); + + g_error ("Signals don't match; expected signal %s path %s, got signal %s path %s\n", + signal_name_to_string (s->signal), s_path_str, + signal_name_to_string (signal), path_str); + + g_free (s_path_str); + g_free (path_str); + + g_assert_not_reached (); + } + + s = g_queue_pop_tail (m->queue); + + signal_free (s); +} + +static void +signal_monitor_row_inserted (GtkTreeModel *model, + GtkTreePath *path, + GtkTreeIter *iter, + gpointer data) +{ + signal_monitor_generic_handler (data, ROW_INSERTED, + model, path); +} + +static void +signal_monitor_row_deleted (GtkTreeModel *model, + GtkTreePath *path, + gpointer data) +{ + signal_monitor_generic_handler (data, ROW_DELETED, + model, path); +} + +static void +signal_monitor_row_changed (GtkTreeModel *model, + GtkTreePath *path, + GtkTreeIter *iter, + gpointer data) +{ + signal_monitor_generic_handler (data, ROW_CHANGED, + model, path); +} + +static void +signal_monitor_row_has_child_toggled (GtkTreeModel *model, + GtkTreePath *path, + GtkTreeIter *iter, + gpointer data) +{ + signal_monitor_generic_handler (data, ROW_HAS_CHILD_TOGGLED, + model, path); +} + +static void +signal_monitor_rows_reordered (GtkTreeModel *model, + GtkTreePath *path, + GtkTreeIter *iter, + gint *new_order, + gpointer data) +{ + signal_monitor_generic_handler (data, ROWS_REORDERED, + model, path); +} + +static SignalMonitor * +signal_monitor_new (GtkTreeModel *client) +{ + SignalMonitor *m; + + m = g_new0 (SignalMonitor, 1); + m->client = g_object_ref (client); + m->queue = g_queue_new (); + + m->signal_ids[ROW_INSERTED] = g_signal_connect (client, + "row-inserted", + G_CALLBACK (signal_monitor_row_inserted), + m); + m->signal_ids[ROW_DELETED] = g_signal_connect (client, + "row-deleted", + G_CALLBACK (signal_monitor_row_deleted), + m); + m->signal_ids[ROW_CHANGED] = g_signal_connect (client, + "row-changed", + G_CALLBACK (signal_monitor_row_changed), + m); + m->signal_ids[ROW_HAS_CHILD_TOGGLED] = g_signal_connect (client, + "row-has-child-toggled", + G_CALLBACK (signal_monitor_row_has_child_toggled), + m); + m->signal_ids[ROWS_REORDERED] = g_signal_connect (client, + "rows-reordered", + G_CALLBACK (signal_monitor_rows_reordered), + m); + + return m; +} + +static void +signal_monitor_free (SignalMonitor *m) +{ + int i; + + for (i = 0; i < LAST_SIGNAL; i++) + g_signal_handler_disconnect (m->client, m->signal_ids[i]); + + g_object_unref (m->client); + + if (m->queue) + g_queue_free (m->queue); + + g_free (m); +} + +static void +signal_monitor_assert_is_empty (SignalMonitor *m) +{ + g_assert (g_queue_is_empty (m->queue)); +} + +static void +signal_monitor_append_signal_path (SignalMonitor *m, + SignalName signal, + GtkTreePath *path) +{ + Signal *s; + + s = signal_new (signal, path); + g_queue_push_head (m->queue, s); +} + +static void +signal_monitor_append_signal (SignalMonitor *m, + SignalName signal, + const gchar *path_string) +{ + Signal *s; + GtkTreePath *path; + + path = gtk_tree_path_new_from_string (path_string); + + s = signal_new (signal, path); + g_queue_push_head (m->queue, s); + + gtk_tree_path_free (path); +} + +/* + * Fixture + */ + +typedef struct +{ + GtkWidget *tree_view; + + GtkTreeStore *store; + GtkTreeModelFilter *filter; + + SignalMonitor *monitor; + + guint block_signals : 1; +} FilterTest; + + +static void +filter_test_store_signal (FilterTest *fixture) +{ + if (fixture->block_signals) + g_signal_stop_emission_by_name (fixture->store, "row-changed"); +} + + +static void +filter_test_setup_generic (FilterTest *fixture, + gconstpointer test_data, + int depth, + gboolean empty, + gboolean unfiltered) +{ + const GtkTreePath *vroot = test_data; + GtkTreeModel *filter; + + fixture->store = create_tree_store (depth, !empty); + + g_signal_connect_swapped (fixture->store, "row-changed", + G_CALLBACK (filter_test_store_signal), fixture); + + /* Please forgive me for casting const away. */ + filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture->store), + (GtkTreePath *)vroot); + fixture->filter = GTK_TREE_MODEL_FILTER (filter); + + if (!unfiltered) + gtk_tree_model_filter_set_visible_column (fixture->filter, 1); + + /* We need a tree view that's listening to get ref counting from that + * side. + */ + fixture->tree_view = gtk_tree_view_new_with_model (filter); + + fixture->monitor = signal_monitor_new (filter); +} + +static void +filter_test_setup (FilterTest *fixture, + gconstpointer test_data) +{ + filter_test_setup_generic (fixture, test_data, 3, FALSE, FALSE); +} + +static void +filter_test_setup_empty (FilterTest *fixture, + gconstpointer test_data) +{ + filter_test_setup_generic (fixture, test_data, 3, TRUE, FALSE); +} + +static void +filter_test_setup_unfiltered (FilterTest *fixture, + gconstpointer test_data) +{ + filter_test_setup_generic (fixture, test_data, 3, FALSE, TRUE); +} + +static void +filter_test_setup_empty_unfiltered (FilterTest *fixture, + gconstpointer test_data) +{ + filter_test_setup_generic (fixture, test_data, 3, TRUE, TRUE); +} + +static GtkTreePath * +strip_virtual_root (GtkTreePath *path, + GtkTreePath *root_path) +{ + GtkTreePath *real_path; + + if (root_path) + { + int j; + int depth = gtk_tree_path_get_depth (path); + int root_depth = gtk_tree_path_get_depth (root_path); + + real_path = gtk_tree_path_new (); + + for (j = 0; j < depth - root_depth; j++) + gtk_tree_path_append_index (real_path, + gtk_tree_path_get_indices (path)[root_depth + j]); + } + else + real_path = gtk_tree_path_copy (path); + + return real_path; +} + +static void +filter_test_append_refilter_signals_recurse (FilterTest *fixture, + GtkTreePath *store_path, + GtkTreePath *filter_path, + int depth, + GtkTreePath *root_path) +{ + int i; + int rows_deleted = 0; + GtkTreeIter iter; + + gtk_tree_path_down (store_path); + gtk_tree_path_down (filter_path); + + gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), + &iter, store_path); + + for (i = 0; i < LEVEL_LENGTH; i++) + { + gboolean visible; + GtkTreePath *real_path; + + gtk_tree_model_get (GTK_TREE_MODEL (fixture->store), &iter, + 1, &visible, + -1); + + if (root_path && + (!gtk_tree_path_is_descendant (store_path, root_path) + || !gtk_tree_path_compare (store_path, root_path))) + { + if (!gtk_tree_path_compare (store_path, root_path)) + { + if (depth > 1 + && gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->store), + &iter)) + { + GtkTreePath *store_copy; + GtkTreePath *filter_copy; + + store_copy = gtk_tree_path_copy (store_path); + filter_copy = gtk_tree_path_copy (filter_path); + filter_test_append_refilter_signals_recurse (fixture, + store_copy, + filter_copy, + depth - 1, + root_path); + gtk_tree_path_free (store_copy); + gtk_tree_path_free (filter_copy); + } + } + + gtk_tree_path_next (store_path); + gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter); + + if (visible) + gtk_tree_path_next (filter_path); + + continue; + } + + real_path = strip_virtual_root (filter_path, root_path); + + if (visible) + { + /* This row will be inserted */ + signal_monitor_append_signal_path (fixture->monitor, ROW_CHANGED, + real_path); + signal_monitor_append_signal_path (fixture->monitor, + ROW_HAS_CHILD_TOGGLED, + real_path); + + if (depth > 1 + && gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->store), + &iter)) + { + GtkTreePath *store_copy; + GtkTreePath *filter_copy; + + store_copy = gtk_tree_path_copy (store_path); + filter_copy = gtk_tree_path_copy (filter_path); + filter_test_append_refilter_signals_recurse (fixture, + store_copy, + filter_copy, + depth - 1, + root_path); + gtk_tree_path_free (store_copy); + gtk_tree_path_free (filter_copy); + } + + gtk_tree_path_next (filter_path); + } + else + { + /* This row will be deleted */ + rows_deleted++; + signal_monitor_append_signal_path (fixture->monitor, ROW_DELETED, + real_path); + } + + gtk_tree_path_free (real_path); + + gtk_tree_path_next (store_path); + gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter); + } + + if (rows_deleted == LEVEL_LENGTH + && gtk_tree_path_get_depth (filter_path) > 1) + { + GtkTreePath *real_path; + + gtk_tree_path_up (store_path); + gtk_tree_path_up (filter_path); + + /* A row-has-child-toggled will be emitted on the parent */ + if (!root_path + || (root_path + && gtk_tree_path_is_descendant (store_path, root_path) + && gtk_tree_path_compare (store_path, root_path))) + { + real_path = strip_virtual_root (filter_path, root_path); + signal_monitor_append_signal_path (fixture->monitor, + ROW_HAS_CHILD_TOGGLED, + real_path); + + gtk_tree_path_free (real_path); + } + } +} + +static void +filter_test_append_refilter_signals (FilterTest *fixture, + int depth) +{ + /* A special function that walks the tree store like the + * model validation functions below. + */ + GtkTreePath *path; + GtkTreePath *filter_path; + + path = gtk_tree_path_new (); + filter_path = gtk_tree_path_new (); + filter_test_append_refilter_signals_recurse (fixture, + path, + filter_path, + depth, + NULL); + gtk_tree_path_free (path); + gtk_tree_path_free (filter_path); +} + +static void +filter_test_append_refilter_signals_with_vroot (FilterTest *fixture, + int depth, + GtkTreePath *root_path) +{ + /* A special function that walks the tree store like the + * model validation functions below. + */ + GtkTreePath *path; + GtkTreePath *filter_path; + + path = gtk_tree_path_new (); + filter_path = gtk_tree_path_new (); + filter_test_append_refilter_signals_recurse (fixture, + path, + filter_path, + depth, + root_path); + gtk_tree_path_free (path); + gtk_tree_path_free (filter_path); +} + +static void +filter_test_enable_filter (FilterTest *fixture) +{ + gtk_tree_model_filter_set_visible_column (fixture->filter, 1); + gtk_tree_model_filter_refilter (fixture->filter); +} + +static void +filter_test_block_signals (FilterTest *fixture) +{ + fixture->block_signals = TRUE; +} + +static void +filter_test_unblock_signals (FilterTest *fixture) +{ + fixture->block_signals = FALSE; +} + +static void +filter_test_teardown (FilterTest *fixture, + gconstpointer test_data) +{ + signal_monitor_free (fixture->monitor); + + g_object_unref (fixture->filter); + g_object_unref (fixture->store); +} + +/* + * Model structure validation + */ + +static void +check_filter_model_recurse (FilterTest *fixture, + GtkTreePath *store_parent_path, + GtkTreePath *filter_parent_path) +{ + int i; + GtkTreeIter store_iter; + GtkTreeIter filter_iter; + gboolean store_has_next, filter_has_next; + + gtk_tree_path_down (store_parent_path); + gtk_tree_path_down (filter_parent_path); + + store_has_next = gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), + &store_iter, store_parent_path); + filter_has_next = gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->filter), + &filter_iter, filter_parent_path); + + for (i = 0; i < LEVEL_LENGTH; i++) + { + gboolean visible; + + g_return_if_fail (store_has_next == TRUE); + + gtk_tree_model_get (GTK_TREE_MODEL (fixture->store), + &store_iter, + 1, &visible, + -1); + + if (visible) + { + GtkTreePath *tmp; + gchar *filter_str, *store_str; + + g_return_if_fail (filter_has_next == TRUE); + + /* Verify path */ + tmp = gtk_tree_model_get_path (GTK_TREE_MODEL (fixture->filter), + &filter_iter); + g_return_if_fail (gtk_tree_path_compare (tmp, filter_parent_path) == 0); + + /* Verify model content */ + gtk_tree_model_get (GTK_TREE_MODEL (fixture->store), + &store_iter, + 0, &store_str, + -1); + gtk_tree_model_get (GTK_TREE_MODEL (fixture->filter), + &filter_iter, + 0, &filter_str, + -1); + + g_return_if_fail (g_strcmp0 (store_str, filter_str) == 0); + + g_free (store_str); + g_free (filter_str); + + if (gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->filter), + &filter_iter)) + { + g_return_if_fail (gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->store), &store_iter)); + + check_filter_model_recurse (fixture, + gtk_tree_path_copy (store_parent_path), + tmp); + } + + gtk_tree_path_next (filter_parent_path); + filter_has_next = gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->filter), &filter_iter); + } + + gtk_tree_path_next (store_parent_path); + store_has_next = gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &store_iter); + } + + /* Both models should have no more content! */ + g_return_if_fail (store_has_next == FALSE); + g_return_if_fail (filter_has_next == FALSE); + + gtk_tree_path_free (store_parent_path); + gtk_tree_path_free (filter_parent_path); +} + +static void +check_filter_model (FilterTest *fixture) +{ + GtkTreePath *path; + + if (fixture->monitor) + signal_monitor_assert_is_empty (fixture->monitor); + + path = gtk_tree_path_new (); + + check_filter_model_recurse (fixture, path, gtk_tree_path_copy (path)); +} + +static void +check_filter_model_with_root (FilterTest *fixture, + GtkTreePath *path) +{ + if (fixture->monitor) + signal_monitor_assert_is_empty (fixture->monitor); + + check_filter_model_recurse (fixture, + gtk_tree_path_copy (path), + gtk_tree_path_new ()); +} + +/* Helpers */ + +static void +check_level_length (GtkTreeModelFilter *filter, + const gchar *level, + const int length) +{ + if (!level) + { + int l = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (filter), NULL); + g_return_if_fail (l == length); + } + else + { + int l; + gboolean retrieved_iter = FALSE; + GtkTreeIter iter; + + retrieved_iter = gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (filter), + &iter, level); + g_return_if_fail (retrieved_iter); + l = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (filter), &iter); + g_return_if_fail (l == length); + } +} + +static void +set_path_visibility (FilterTest *fixture, + const gchar *path, + gboolean visible) +{ + GtkTreeIter store_iter; + + gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), + &store_iter, path); + gtk_tree_store_set (fixture->store, &store_iter, + 1, visible, + -1); +} + +#if 0 +static void +insert_path_with_visibility (FilterTest *fixture, + const gchar *path_string, + gboolean visible) +{ + int position; + GtkTreePath *path; + GtkTreeIter parent, iter; + + path = gtk_tree_path_new_from_string (path_string); + position = gtk_tree_path_get_indices (path)[gtk_tree_path_get_depth (path)]; + gtk_tree_path_up (path); + + if (gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &parent, path)) + { + gtk_tree_store_insert (fixture->store, &iter, &parent, position); + create_tree_store_set_values (fixture->store, &iter, visible); + } + gtk_tree_path_free (path); +} +#endif + +/* + * The actual tests. + */ + +static void +verify_test_suite (FilterTest *fixture, + gconstpointer user_data) +{ + check_filter_model (fixture); +} + +static void +verify_test_suite_vroot (FilterTest *fixture, + gconstpointer user_data) +{ + check_filter_model_with_root (fixture, (GtkTreePath *)user_data); +} + + +static void +filled_hide_root_level (FilterTest *fixture, + gconstpointer user_data) +{ + signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "2"); + set_path_visibility (fixture, "2", FALSE); + check_filter_model (fixture); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1); + + signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0"); + set_path_visibility (fixture, "0", FALSE); + check_filter_model (fixture); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2); + + signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "2"); + set_path_visibility (fixture, "4", FALSE); + check_filter_model (fixture); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 3); + + + /* Hide remaining */ + signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0"); + signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0"); + + set_path_visibility (fixture, "1", FALSE); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 4); + + set_path_visibility (fixture, "3", FALSE); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 5); + + check_filter_model (fixture); + + /* Show some */ + signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0"); + signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "1"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1"); + + set_path_visibility (fixture, "1", TRUE); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 4); + + set_path_visibility (fixture, "3", TRUE); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 3); + + check_filter_model (fixture); +} + +static void +filled_hide_child_levels (FilterTest *fixture, + gconstpointer user_data) +{ + signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:2"); + set_path_visibility (fixture, "0:2", FALSE); + check_filter_model (fixture); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH); + check_level_length (fixture->filter, "0", LEVEL_LENGTH - 1); + + signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:3"); + set_path_visibility (fixture, "0:4", FALSE); + check_filter_model (fixture); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH); + check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2); + + set_path_visibility (fixture, "0:4:3", FALSE); + check_filter_model (fixture); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH); + check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2); + + set_path_visibility (fixture, "0:4:0", FALSE); + set_path_visibility (fixture, "0:4:1", FALSE); + set_path_visibility (fixture, "0:4:2", FALSE); + set_path_visibility (fixture, "0:4:4", FALSE); + check_filter_model (fixture); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH); + check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2); + + /* Since "0:2" is hidden, "0:4" must be "0:3" in the filter model */ + signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:3"); + /* FIXME: Actually, the filter model should not be emitted the + * row-has-child-toggled signal here. *However* an extraneous emission + * of this signal does not hurt and is allowed. + */ + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:3"); + set_path_visibility (fixture, "0:4", TRUE); + check_filter_model (fixture); + check_level_length (fixture->filter, "0:3", 0); + + signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:2"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:2"); + set_path_visibility (fixture, "0:2", TRUE); + check_filter_model (fixture); + check_level_length (fixture->filter, "0:2", LEVEL_LENGTH); + check_level_length (fixture->filter, "0:3", LEVEL_LENGTH); + check_level_length (fixture->filter, "0:4", 0); + + signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:4:0"); + /* Once 0:4:0 got inserted, 0:4 became a parent */ + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4:0"); + signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:4:1"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4:1"); + + set_path_visibility (fixture, "0:4:2", TRUE); + set_path_visibility (fixture, "0:4:4", TRUE); + signal_monitor_assert_is_empty (fixture->monitor); + check_level_length (fixture->filter, "0:4", 2); +} + + +static void +filled_vroot_hide_root_level (FilterTest *fixture, + gconstpointer user_data) +{ + GtkTreePath *path = (GtkTreePath *)user_data; + + /* These changes do not affect the filter's root level */ + set_path_visibility (fixture, "0", FALSE); + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH); + check_level_length (fixture->filter, "0", LEVEL_LENGTH); + + set_path_visibility (fixture, "4", FALSE); + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH); + check_level_length (fixture->filter, "0", LEVEL_LENGTH); + + /* Even though we set the virtual root parent node to FALSE, + * the virtual root contents remain. + */ + set_path_visibility (fixture, "2", FALSE); + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH); + check_level_length (fixture->filter, "0", LEVEL_LENGTH); + + /* No change */ + set_path_visibility (fixture, "1", FALSE); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH); + check_level_length (fixture->filter, "0", LEVEL_LENGTH); + + set_path_visibility (fixture, "3", FALSE); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH); + check_level_length (fixture->filter, "0", LEVEL_LENGTH); + + check_filter_model_with_root (fixture, path); + + /* Show some */ + set_path_visibility (fixture, "2", TRUE); + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH); + check_level_length (fixture->filter, "0", LEVEL_LENGTH); + + set_path_visibility (fixture, "1", TRUE); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH); + check_level_length (fixture->filter, "0", LEVEL_LENGTH); + + set_path_visibility (fixture, "3", TRUE); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH); + check_level_length (fixture->filter, "0", LEVEL_LENGTH); + + check_filter_model_with_root (fixture, path); + + /* Now test changes in the virtual root level */ + signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "2"); + set_path_visibility (fixture, "2:2", FALSE); + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1); + + signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "3"); + set_path_visibility (fixture, "2:4", FALSE); + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2); + + set_path_visibility (fixture, "1:4", FALSE); + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2); + + signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "3"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "3"); + set_path_visibility (fixture, "2:4", TRUE); + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1); + + set_path_visibility (fixture, "2", FALSE); + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1); + + signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0"); + signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0"); + signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0"); + signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0"); + set_path_visibility (fixture, "2:0", FALSE); + set_path_visibility (fixture, "2:1", FALSE); + set_path_visibility (fixture, "2:2", FALSE); + set_path_visibility (fixture, "2:3", FALSE); + set_path_visibility (fixture, "2:4", FALSE); + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, 0); + + set_path_visibility (fixture, "2", TRUE); + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, 0); + + set_path_visibility (fixture, "1:4", FALSE); + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, 0); + + signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0"); + set_path_visibility (fixture, "2:4", TRUE); + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 4); + + signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0"); + set_path_visibility (fixture, "2:4", FALSE); + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, 0); + + set_path_visibility (fixture, "2", FALSE); + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, 0); + + signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0"); + signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "1"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1"); + signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "2"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2"); + set_path_visibility (fixture, "2:0", TRUE); + set_path_visibility (fixture, "2:1", TRUE); + set_path_visibility (fixture, "2:2", TRUE); + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2); + + set_path_visibility (fixture, "2", TRUE); + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2); +} + +static void +filled_vroot_hide_child_levels (FilterTest *fixture, + gconstpointer user_data) +{ + GtkTreePath *path = (GtkTreePath *)user_data; + + signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:2"); + set_path_visibility (fixture, "2:0:2", FALSE); + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH); + check_level_length (fixture->filter, "0", LEVEL_LENGTH - 1); + + signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:3"); + set_path_visibility (fixture, "2:0:4", FALSE); + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH); + check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2); + + set_path_visibility (fixture, "2:0:4:3", FALSE); + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH); + check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2); + + set_path_visibility (fixture, "2:0:4:0", FALSE); + set_path_visibility (fixture, "2:0:4:1", FALSE); + set_path_visibility (fixture, "2:0:4:2", FALSE); + set_path_visibility (fixture, "2:0:4:4", FALSE); + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH); + check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2); + + /* Since "0:2" is hidden, "0:4" must be "0:3" in the filter model */ + signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:3"); + /* FIXME: Actually, the filter model should not be emitted the + * row-has-child-toggled signal here. *However* an extraneous emission + * of this signal does not hurt and is allowed. + */ + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:3"); + set_path_visibility (fixture, "2:0:4", TRUE); + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, "0:3", 0); + + signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:2"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:2"); + set_path_visibility (fixture, "2:0:2", TRUE); + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, "0:2", LEVEL_LENGTH); + check_level_length (fixture->filter, "0:3", LEVEL_LENGTH); + check_level_length (fixture->filter, "0:4", 0); + + /* FIXME: Inconsistency! For the non-vroot case we also receive two + * row-has-child-toggled signals here. + */ + signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:4:0"); + /* Once 0:4:0 got inserted, 0:4 became a parent */ + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4"); + signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:4:1"); + set_path_visibility (fixture, "2:0:4:2", TRUE); + set_path_visibility (fixture, "2:0:4:4", TRUE); + check_level_length (fixture->filter, "0:4", 2); +} + + +static void +empty_show_nodes (FilterTest *fixture, + gconstpointer user_data) +{ + check_filter_model (fixture); + check_level_length (fixture->filter, NULL, 0); + + signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0"); + set_path_visibility (fixture, "3", TRUE); + check_filter_model (fixture); + check_level_length (fixture->filter, NULL, 1); + check_level_length (fixture->filter, "0", 0); + + set_path_visibility (fixture, "3:2:2", TRUE); + check_filter_model (fixture); + check_level_length (fixture->filter, NULL, 1); + check_level_length (fixture->filter, "0", 0); + + signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:0"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:0"); + set_path_visibility (fixture, "3:2", TRUE); + check_filter_model (fixture); + check_level_length (fixture->filter, NULL, 1); + check_level_length (fixture->filter, "0", 1); + check_level_length (fixture->filter, "0:0", 1); + check_level_length (fixture->filter, "0:0:0", 0); + + signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0"); + set_path_visibility (fixture, "3", FALSE); + check_filter_model (fixture); + check_level_length (fixture->filter, NULL, 0); + + signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0"); + set_path_visibility (fixture, "3:2:1", TRUE); + set_path_visibility (fixture, "3", TRUE); + check_filter_model (fixture); + check_level_length (fixture->filter, NULL, 1); + check_level_length (fixture->filter, "0", 1); + check_level_length (fixture->filter, "0:0", 2); + check_level_length (fixture->filter, "0:0:0", 0); +} + +static void +empty_show_multiple_nodes (FilterTest *fixture, + gconstpointer user_data) +{ + GtkTreeIter iter; + GtkTreePath *changed_path; + + check_filter_model (fixture); + check_level_length (fixture->filter, NULL, 0); + + signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0"); + signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "1"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1"); + signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "1"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1"); + + /* We simulate a change in visible func condition with this. The + * visibility state of multiple nodes changes at once, we emit row-changed + * for these nodes (and others) after that. + */ + filter_test_block_signals (fixture); + set_path_visibility (fixture, "3", TRUE); + set_path_visibility (fixture, "4", TRUE); + filter_test_unblock_signals (fixture); + + changed_path = gtk_tree_path_new (); + gtk_tree_path_append_index (changed_path, 2); + gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), + &iter, changed_path); + gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store), + changed_path, &iter); + + gtk_tree_path_next (changed_path); + gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter); + gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store), + changed_path, &iter); + + gtk_tree_path_next (changed_path); + gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter); + gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store), + changed_path, &iter); + + gtk_tree_path_free (changed_path); + + check_filter_model (fixture); + check_level_length (fixture->filter, NULL, 2); + check_level_length (fixture->filter, "0", 0); + + set_path_visibility (fixture, "3:2:2", TRUE); + check_filter_model (fixture); + check_level_length (fixture->filter, NULL, 2); + check_level_length (fixture->filter, "0", 0); + + signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:0"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:0"); + set_path_visibility (fixture, "3:2", TRUE); + check_filter_model (fixture); + check_level_length (fixture->filter, NULL, 2); + check_level_length (fixture->filter, "0", 1); + check_level_length (fixture->filter, "0:0", 1); + check_level_length (fixture->filter, "0:0:0", 0); + + signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0"); + set_path_visibility (fixture, "3", FALSE); + check_filter_model (fixture); + check_level_length (fixture->filter, NULL, 1); + + signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0"); + set_path_visibility (fixture, "3:2:1", TRUE); + set_path_visibility (fixture, "3", TRUE); + check_filter_model (fixture); + check_level_length (fixture->filter, NULL, 2); + check_level_length (fixture->filter, "0", 1); + check_level_length (fixture->filter, "0:0", 2); + check_level_length (fixture->filter, "0:0:0", 0); +} + +static void +empty_vroot_show_nodes (FilterTest *fixture, + gconstpointer user_data) +{ + GtkTreePath *path = (GtkTreePath *)user_data; + + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, 0); + + set_path_visibility (fixture, "2", TRUE); + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, 0); + + set_path_visibility (fixture, "2:2:2", TRUE); + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, 0); + + signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0"); + set_path_visibility (fixture, "2:2", TRUE); + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, 1); + check_level_length (fixture->filter, "0", 1); + check_level_length (fixture->filter, "0:0", 0); + + set_path_visibility (fixture, "3", TRUE); + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, 1); + + signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0"); + set_path_visibility (fixture, "2:2", FALSE); + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, 0); + + signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0"); + set_path_visibility (fixture, "2:2:1", TRUE); + set_path_visibility (fixture, "2:2", TRUE); + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, 1); + check_level_length (fixture->filter, "0", 2); + check_level_length (fixture->filter, "0:1", 0); +} + +static void +empty_vroot_show_multiple_nodes (FilterTest *fixture, + gconstpointer user_data) +{ + GtkTreeIter iter; + GtkTreePath *changed_path; + GtkTreePath *path = (GtkTreePath *)user_data; + + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, 0); + + /* We simulate a change in visible func condition with this. The + * visibility state of multiple nodes changes at once, we emit row-changed + * for these nodes (and others) after that. + */ + filter_test_block_signals (fixture); + set_path_visibility (fixture, "2", TRUE); + set_path_visibility (fixture, "3", TRUE); + filter_test_unblock_signals (fixture); + + changed_path = gtk_tree_path_new (); + gtk_tree_path_append_index (changed_path, 1); + gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), + &iter, changed_path); + gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store), + changed_path, &iter); + + gtk_tree_path_next (changed_path); + gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter); + gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store), + changed_path, &iter); + + gtk_tree_path_next (changed_path); + gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter); + gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store), + changed_path, &iter); + + gtk_tree_path_next (changed_path); + gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter); + gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store), + changed_path, &iter); + + gtk_tree_path_free (changed_path); + + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, 0); + + set_path_visibility (fixture, "2:2:2", TRUE); + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, 0); + + signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0"); + signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "1"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1"); + + /* Again, we simulate a call to refilter */ + filter_test_block_signals (fixture); + set_path_visibility (fixture, "2:2", TRUE); + set_path_visibility (fixture, "2:3", TRUE); + filter_test_unblock_signals (fixture); + + changed_path = gtk_tree_path_new (); + gtk_tree_path_append_index (changed_path, 2); + gtk_tree_path_append_index (changed_path, 1); + gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), + &iter, changed_path); + gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store), + changed_path, &iter); + + gtk_tree_path_next (changed_path); + gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter); + gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store), + changed_path, &iter); + + gtk_tree_path_next (changed_path); + gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter); + gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store), + changed_path, &iter); + + gtk_tree_path_next (changed_path); + gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter); + gtk_tree_model_row_changed (GTK_TREE_MODEL (fixture->store), + changed_path, &iter); + + gtk_tree_path_free (changed_path); + + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, 2); + check_level_length (fixture->filter, "0", 1); + check_level_length (fixture->filter, "0:0", 0); + + set_path_visibility (fixture, "3", TRUE); + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, 2); + + signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0"); + set_path_visibility (fixture, "2:2", FALSE); + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, 1); + + signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0"); + set_path_visibility (fixture, "2:2:1", TRUE); + set_path_visibility (fixture, "2:2", TRUE); + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, 2); + check_level_length (fixture->filter, "0", 2); + check_level_length (fixture->filter, "0:1", 0); +} + + +static void +unfiltered_hide_single (FilterTest *fixture, + gconstpointer user_data) + +{ + signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2"); + set_path_visibility (fixture, "2", FALSE); + + signal_monitor_assert_is_empty (fixture->monitor); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH); + + /* The view only shows the root level, so the filter model only has + * the first two levels cached. + */ + filter_test_append_refilter_signals (fixture, 2); + filter_test_enable_filter (fixture); + + check_filter_model (fixture); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1); +} + +static void +unfiltered_hide_single_child (FilterTest *fixture, + gconstpointer user_data) + +{ + signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2"); + set_path_visibility (fixture, "2:2", FALSE); + + signal_monitor_assert_is_empty (fixture->monitor); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH); + check_level_length (fixture->filter, "2", LEVEL_LENGTH); + + /* The view only shows the root level, so the filter model only has + * the first two levels cached. + */ + filter_test_append_refilter_signals (fixture, 2); + filter_test_enable_filter (fixture); + + check_filter_model (fixture); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH); + check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1); +} + +static void +unfiltered_hide_single_multi_level (FilterTest *fixture, + gconstpointer user_data) + +{ + /* This row is not shown, so its signal is not propagated */ + set_path_visibility (fixture, "2:2:2", FALSE); + + signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2"); + set_path_visibility (fixture, "2:2", FALSE); + + signal_monitor_assert_is_empty (fixture->monitor); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH); + check_level_length (fixture->filter, "2", LEVEL_LENGTH); + check_level_length (fixture->filter, "2:2", LEVEL_LENGTH); + + /* The view only shows the root level, so the filter model only has + * the first two levels cached. + */ + filter_test_append_refilter_signals (fixture, 2); + filter_test_enable_filter (fixture); + + check_filter_model (fixture); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH); + check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1); + + signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "2:2"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2"); + set_path_visibility (fixture, "2:2", TRUE); + + check_filter_model (fixture); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH); + check_level_length (fixture->filter, "2", LEVEL_LENGTH); + check_level_length (fixture->filter, "2:2", LEVEL_LENGTH - 1); +} + + +static void +unfiltered_vroot_hide_single (FilterTest *fixture, + gconstpointer user_data) + +{ + GtkTreePath *path = (GtkTreePath *)user_data; + + signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2"); + set_path_visibility (fixture, "2:2", FALSE); + + signal_monitor_assert_is_empty (fixture->monitor); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH); + + /* The view only shows the root level, so the filter model only has + * the first two levels cached. (We add an additional level to + * take the virtual root into account). + */ + filter_test_append_refilter_signals_with_vroot (fixture, 3, path); + filter_test_enable_filter (fixture); + + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1); +} + +static void +unfiltered_vroot_hide_single_child (FilterTest *fixture, + gconstpointer user_data) + +{ + GtkTreePath *path = (GtkTreePath *)user_data; + + signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2"); + set_path_visibility (fixture, "2:2:2", FALSE); + + signal_monitor_assert_is_empty (fixture->monitor); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH); + check_level_length (fixture->filter, "2", LEVEL_LENGTH); + + /* The view only shows the root level, so the filter model only has + * the first two levels cached. (We add an additional level to take + * the virtual root into account). + */ + filter_test_append_refilter_signals_with_vroot (fixture, 3, path); + filter_test_enable_filter (fixture); + + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH); + check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1); +} + +static void +unfiltered_vroot_hide_single_multi_level (FilterTest *fixture, + gconstpointer user_data) + +{ + GtkTreePath *path = (GtkTreePath *)user_data; + + /* This row is not shown, so its signal is not propagated */ + set_path_visibility (fixture, "2:2:2:2", FALSE); + + signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2"); + set_path_visibility (fixture, "2:2:2", FALSE); + + signal_monitor_assert_is_empty (fixture->monitor); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH); + check_level_length (fixture->filter, "2", LEVEL_LENGTH); + check_level_length (fixture->filter, "2:2", LEVEL_LENGTH); + + /* The view only shows the root level, so the filter model only has + * the first two levels cached. + */ + filter_test_append_refilter_signals_with_vroot (fixture, 3, path); + filter_test_enable_filter (fixture); + + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH); + check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1); + + signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "2:2"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2"); + set_path_visibility (fixture, "2:2:2", TRUE); + + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH); + check_level_length (fixture->filter, "2", LEVEL_LENGTH); + check_level_length (fixture->filter, "2:2", LEVEL_LENGTH - 1); +} + + + +static void +unfiltered_show_single (FilterTest *fixture, + gconstpointer user_data) + +{ + signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2"); + set_path_visibility (fixture, "2", TRUE); + + signal_monitor_assert_is_empty (fixture->monitor); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH); + + /* The view only shows the root level, so the filter model only has + * the first two levels cached. + */ + filter_test_append_refilter_signals (fixture, 2); + filter_test_enable_filter (fixture); + + check_filter_model (fixture); + check_level_length (fixture->filter, NULL, 1); +} + +static void +unfiltered_show_single_child (FilterTest *fixture, + gconstpointer user_data) + +{ + signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2"); + set_path_visibility (fixture, "2:2", TRUE); + + signal_monitor_assert_is_empty (fixture->monitor); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH); + check_level_length (fixture->filter, "2", LEVEL_LENGTH); + + /* The view only shows the root level, so the filter model only has + * the first two levels cached. + */ + filter_test_append_refilter_signals (fixture, 3); + filter_test_enable_filter (fixture); + + check_filter_model (fixture); + check_level_length (fixture->filter, NULL, 0); + + /* From here we are filtered, "2" in the real model is "0" in the filter + * model. + */ + signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0"); + set_path_visibility (fixture, "2", TRUE); + signal_monitor_assert_is_empty (fixture->monitor); + check_level_length (fixture->filter, NULL, 1); + check_level_length (fixture->filter, "0", 1); +} + +static void +unfiltered_show_single_multi_level (FilterTest *fixture, + gconstpointer user_data) + +{ + /* The view is not showing this row (collapsed state), so it is not + * referenced. The signal should not go through. + */ + set_path_visibility (fixture, "2:2:2", TRUE); + + signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2"); + set_path_visibility (fixture, "2:2", TRUE); + + signal_monitor_assert_is_empty (fixture->monitor); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH); + check_level_length (fixture->filter, "2", LEVEL_LENGTH); + check_level_length (fixture->filter, "2:2", LEVEL_LENGTH); + + /* The view only shows the root level, so the filter model only has + * the first two levels cached. + */ + filter_test_append_refilter_signals (fixture, 3); + filter_test_enable_filter (fixture); + + check_filter_model (fixture); + check_level_length (fixture->filter, NULL, 0); + + /* From here we are filtered, "2" in the real model is "0" in the filter + * model. + */ + signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0"); + set_path_visibility (fixture, "2", TRUE); + check_filter_model (fixture); + check_level_length (fixture->filter, NULL, 1); + check_level_length (fixture->filter, "0", 1); + check_level_length (fixture->filter, "0:0", 1); +} + + +static void +unfiltered_vroot_show_single (FilterTest *fixture, + gconstpointer user_data) + +{ + GtkTreePath *path = (GtkTreePath *)user_data; + + signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2"); + set_path_visibility (fixture, "2:2", TRUE); + + signal_monitor_assert_is_empty (fixture->monitor); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH); + + /* The view only shows the root level, so the filter model only has + * the first two levels cached. + */ + filter_test_append_refilter_signals_with_vroot (fixture, 3, path); + filter_test_enable_filter (fixture); + + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, 1); +} + +static void +unfiltered_vroot_show_single_child (FilterTest *fixture, + gconstpointer user_data) + +{ + GtkTreePath *path = (GtkTreePath *)user_data; + + signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2"); + set_path_visibility (fixture, "2:2:2", TRUE); + + signal_monitor_assert_is_empty (fixture->monitor); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH); + check_level_length (fixture->filter, "2", LEVEL_LENGTH); + + /* The view only shows the root level, so the filter model only has + * the first two levels cached. + */ + filter_test_append_refilter_signals_with_vroot (fixture, 2, path); + filter_test_enable_filter (fixture); + + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, 0); + + /* From here we are filtered, "2" in the real model is "0" in the filter + * model. + */ + signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0"); + set_path_visibility (fixture, "2:2", TRUE); + signal_monitor_assert_is_empty (fixture->monitor); + check_level_length (fixture->filter, NULL, 1); + check_level_length (fixture->filter, "0", 1); +} + +static void +unfiltered_vroot_show_single_multi_level (FilterTest *fixture, + gconstpointer user_data) + +{ + GtkTreePath *path = (GtkTreePath *)user_data; + + /* The view is not showing this row (collapsed state), so it is not + * referenced. The signal should not go through. + */ + set_path_visibility (fixture, "2:2:2:2", TRUE); + + signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2"); + set_path_visibility (fixture, "2:2:2", TRUE); + + signal_monitor_assert_is_empty (fixture->monitor); + check_level_length (fixture->filter, NULL, LEVEL_LENGTH); + check_level_length (fixture->filter, "2", LEVEL_LENGTH); + check_level_length (fixture->filter, "2:2", LEVEL_LENGTH); + + /* The view only shows the root level, so the filter model only has + * the first two levels cached. + */ + filter_test_append_refilter_signals_with_vroot (fixture, 4, path); + filter_test_enable_filter (fixture); + + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, 0); + + /* From here we are filtered, "2" in the real model is "0" in the filter + * model. + */ + signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0"); + signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0"); + set_path_visibility (fixture, "2:2", TRUE); + check_filter_model_with_root (fixture, path); + check_level_length (fixture->filter, NULL, 1); + check_level_length (fixture->filter, "0", 1); + check_level_length (fixture->filter, "0:0", 1); +} + + +static gboolean +specific_path_dependent_filter_func (GtkTreeModel *model, + GtkTreeIter *iter, + gpointer data) +{ + GtkTreePath *path; + + path = gtk_tree_model_get_path (model, iter); + if (gtk_tree_path_get_indices (path)[0] < 4) + return FALSE; + + return TRUE; +} + +static void +specific_path_dependent_filter (void) +{ + int i; + GtkTreeIter iter; + GtkListStore *list; + GtkTreeModel *sort; + GtkTreeModel *filter; + + list = gtk_list_store_new (1, G_TYPE_INT); + gtk_list_store_insert_with_values (list, &iter, 0, 0, 1, -1); + gtk_list_store_insert_with_values (list, &iter, 1, 0, 2, -1); + gtk_list_store_insert_with_values (list, &iter, 2, 0, 3, -1); + gtk_list_store_insert_with_values (list, &iter, 3, 0, 4, -1); + gtk_list_store_insert_with_values (list, &iter, 4, 0, 5, -1); + gtk_list_store_insert_with_values (list, &iter, 5, 0, 6, -1); + gtk_list_store_insert_with_values (list, &iter, 6, 0, 7, -1); + gtk_list_store_insert_with_values (list, &iter, 7, 0, 8, -1); + + sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (list)); + filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (sort), NULL); + gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter), + specific_path_dependent_filter_func, + NULL, NULL); + + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort), 0, + GTK_SORT_DESCENDING); + + for (i = 0; i < 4; i++) + { + if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (list), &iter, + NULL, 1)) + gtk_list_store_remove (list, &iter); + + if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (list), &iter, + NULL, 2)) + gtk_list_store_remove (list, &iter); + } +} + + +static gboolean +specific_append_after_collapse_visible_func (GtkTreeModel *model, + GtkTreeIter *iter, + gpointer data) +{ + gint number; + gboolean hide_negative_numbers; + + gtk_tree_model_get (model, iter, 1, &number, -1); + hide_negative_numbers = GPOINTER_TO_INT (g_object_get_data (data, "private-hide-negative-numbers")); + + return (number >= 0 || !hide_negative_numbers); +} + +static void +specific_append_after_collapse (void) +{ + /* This test is based on one of the test cases I found in my + * old test cases directory. I unfortunately do not have a record + * from who this test case originated. -Kris. + * + * General idea: + * - Construct tree. + * - Show tree, expand, collapse. + * - Add a row. + */ + + GtkTreeIter iter; + GtkTreeIter child_iter; + GtkTreeIter child_iter2; + GtkTreePath *append_path; + GtkTreeStore *store; + GtkTreeModel *filter; + GtkTreeModel *sort; + + GtkWidget *window; + GtkWidget *tree_view; + + store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_INT); + + filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL); + g_object_set_data (G_OBJECT (filter), "private-hide-negative-numbers", + GINT_TO_POINTER (FALSE)); + gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter), + specific_append_after_collapse_visible_func, + filter, NULL); + + sort = gtk_tree_model_sort_new_with_model (filter); + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + tree_view = gtk_tree_view_new_with_model (sort); + gtk_container_add (GTK_CONTAINER (window), tree_view); + gtk_widget_realize (tree_view); + + while (gtk_events_pending ()) + gtk_main_iteration (); + + gtk_tree_store_prepend (store, &iter, NULL); + gtk_tree_store_set (store, &iter, + 0, "hallo", 1, 1, -1); + + gtk_tree_store_append (store, &child_iter, &iter); + gtk_tree_store_set (store, &child_iter, + 0, "toemaar", 1, 1, -1); + + gtk_tree_store_append (store, &child_iter2, &child_iter); + gtk_tree_store_set (store, &child_iter2, + 0, "very deep", 1, 1, -1); + + append_path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &child_iter2); + + gtk_tree_store_append (store, &child_iter, &iter); + gtk_tree_store_set (store, &child_iter, + 0, "sja", 1, 1, -1); + + gtk_tree_store_append (store, &child_iter, &iter); + gtk_tree_store_set (store, &child_iter, + 0, "some word", 1, -1, -1); + + /* Expand and collapse the tree */ + gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view)); + while (gtk_events_pending ()) + gtk_main_iteration (); + + gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view)); + while (gtk_events_pending ()) + gtk_main_iteration (); + + /* Add another it */ + g_object_set_data (G_OBJECT (filter), "private-hide-negative-numbers", + GINT_TO_POINTER (TRUE)); + + if (gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, append_path)) + { + gtk_tree_store_append (store, &child_iter, &iter); + gtk_tree_store_set (store, &child_iter, + 0, "new new new !!", 1, 1, -1); + } + gtk_tree_path_free (append_path); + + /* Expand */ + gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view)); + while (gtk_events_pending ()) + gtk_main_iteration (); +} + + +static gint +specific_sort_filter_remove_node_compare_func (GtkTreeModel *model, + GtkTreeIter *iter1, + GtkTreeIter *iter2, + gpointer data) +{ + return -1; +} + +static gboolean +specific_sort_filter_remove_node_visible_func (GtkTreeModel *model, + GtkTreeIter *iter, + gpointer data) +{ + char *item = NULL; + + /* Do reference the model */ + gtk_tree_model_get (model, iter, 0, &item, -1); + g_free (item); + + return FALSE; +} + +static void +specific_sort_filter_remove_node (void) +{ + /* This test is based on one of the test cases I found in my + * old test cases directory. I unfortunately do not have a record + * from who this test case originated. -Kris. + * + * General idea: + * - Create tree store, sort, filter models. The sort model has + * a default sort func that is enabled, filter model a visible func + * that defaults to returning FALSE. + * - Remove a node from the tree store. + */ + + GtkTreeIter iter; + GtkTreeStore *store; + GtkTreeModel *filter; + GtkTreeModel *sort; + + GtkWidget *window; + GtkWidget *tree_view; + + store = gtk_tree_store_new (1, G_TYPE_STRING); + gtk_tree_store_append (store, &iter, NULL); + gtk_tree_store_set (store, &iter, 0, "Hello1", -1); + + gtk_tree_store_append (store, &iter, NULL); + gtk_tree_store_set (store, &iter, 0, "Hello2", -1); + + sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store)); + gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (sort), + specific_sort_filter_remove_node_compare_func, NULL, NULL); + + filter = gtk_tree_model_filter_new (sort, NULL); + gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter), + specific_sort_filter_remove_node_visible_func, + filter, NULL); + + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + tree_view = gtk_tree_view_new_with_model (filter); + gtk_container_add (GTK_CONTAINER (window), tree_view); + gtk_widget_realize (tree_view); + + while (gtk_events_pending ()) + gtk_main_iteration (); + + /* Remove a node */ + gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter); + gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter); + gtk_tree_store_remove (store, &iter); + + while (gtk_events_pending ()) + gtk_main_iteration (); +} + + +static void +specific_sort_filter_remove_root (void) +{ + /* This test is based on one of the test cases I found in my + * old test cases directory. I unfortunately do not have a record + * from who this test case originated. -Kris. + */ + + GtkTreeModel *model, *sort, *filter; + GtkTreeIter root, mid, leaf; + GtkTreePath *path; + + model = GTK_TREE_MODEL (gtk_tree_store_new (1, G_TYPE_INT)); + gtk_tree_store_append (GTK_TREE_STORE (model), &root, NULL); + gtk_tree_store_append (GTK_TREE_STORE (model), &mid, &root); + gtk_tree_store_append (GTK_TREE_STORE (model), &leaf, &mid); + + path = gtk_tree_model_get_path (model, &mid); + + sort = gtk_tree_model_sort_new_with_model (model); + filter = gtk_tree_model_filter_new (sort, path); + + gtk_tree_store_remove (GTK_TREE_STORE (model), &root); + + g_object_unref (filter); + g_object_unref (sort); + g_object_unref (model); +} + + +static void +specific_root_mixed_visibility (void) +{ + int i; + GtkTreeModel *filter; + /* A bit nasty, apologies */ + FilterTest fixture; + + fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN); + + for (i = 0; i < LEVEL_LENGTH; i++) + { + GtkTreeIter iter; + + gtk_tree_store_insert (fixture.store, &iter, NULL, i); + if (i % 2 == 0) + create_tree_store_set_values (fixture.store, &iter, TRUE); + else + create_tree_store_set_values (fixture.store, &iter, FALSE); + } + + filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL); + fixture.filter = GTK_TREE_MODEL_FILTER (filter); + fixture.monitor = NULL; + + gtk_tree_model_filter_set_visible_column (fixture.filter, 1); + + /* In order to trigger the potential bug, we should not access + * the filter model here (so don't call the check functions). + */ + + /* Change visibility of an odd row to TRUE */ + set_path_visibility (&fixture, "3", TRUE); + check_filter_model (&fixture); + check_level_length (fixture.filter, NULL, 4); +} + + + +static gboolean +specific_has_child_filter_filter_func (GtkTreeModel *model, + GtkTreeIter *iter, + gpointer data) +{ + return gtk_tree_model_iter_has_child (model, iter); +} + +static void +specific_has_child_filter (void) +{ + GtkTreeModel *filter; + GtkTreeIter iter, root; + /* A bit nasty, apologies */ + FilterTest fixture; + + fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN); + filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL); + fixture.filter = GTK_TREE_MODEL_FILTER (filter); + fixture.monitor = NULL; + + /* We will filter on parent state using a filter function. We will + * manually keep the boolean column in sync, so that we can use + * check_filter_model() to check the consistency of the model. + */ + /* FIXME: We need a check_filter_model() that is not tied to LEVEL_LENGTH + * to be able to check the structure here. We keep the calls to + * check_filter_model() commented out until then. + */ + gtk_tree_model_filter_set_visible_func (fixture.filter, + specific_has_child_filter_filter_func, + NULL, NULL); + + gtk_tree_store_append (fixture.store, &root, NULL); + create_tree_store_set_values (fixture.store, &root, FALSE); + + /* check_filter_model (&fixture); */ + check_level_length (fixture.filter, NULL, 0); + + gtk_tree_store_append (fixture.store, &iter, &root); + create_tree_store_set_values (fixture.store, &iter, TRUE); + + /* Parent must now be visible. Do the level length check first, + * to avoid modifying the child model triggering a row-changed to + * the filter model. + */ + check_level_length (fixture.filter, NULL, 1); + check_level_length (fixture.filter, "0", 0); + + set_path_visibility (&fixture, "0", TRUE); + /* check_filter_model (&fixture); */ + + gtk_tree_store_append (fixture.store, &root, NULL); + check_level_length (fixture.filter, NULL, 1); + + gtk_tree_store_append (fixture.store, &iter, &root); + check_level_length (fixture.filter, NULL, 2); + check_level_length (fixture.filter, "1", 0); + + create_tree_store_set_values (fixture.store, &root, TRUE); + create_tree_store_set_values (fixture.store, &iter, TRUE); + + /* check_filter_model (&fixture); */ + + gtk_tree_store_append (fixture.store, &iter, &root); + create_tree_store_set_values (fixture.store, &iter, TRUE); + check_level_length (fixture.filter, NULL, 2); + check_level_length (fixture.filter, "0", 0); + check_level_length (fixture.filter, "1", 0); + + /* Now remove one of the remaining child rows */ + gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store), + &iter, "0:0"); + gtk_tree_store_remove (fixture.store, &iter); + + check_level_length (fixture.filter, NULL, 1); + check_level_length (fixture.filter, "0", 0); + + set_path_visibility (&fixture, "0", FALSE); + /* check_filter_model (&fixture); */ +} + + +static gboolean +specific_root_has_child_filter_filter_func (GtkTreeModel *model, + GtkTreeIter *iter, + gpointer data) +{ + int depth; + GtkTreePath *path; + + path = gtk_tree_model_get_path (model, iter); + depth = gtk_tree_path_get_depth (path); + gtk_tree_path_free (path); + + if (depth > 1) + return TRUE; + /* else */ + return gtk_tree_model_iter_has_child (model, iter); +} + +static void +specific_root_has_child_filter (void) +{ + GtkTreeModel *filter; + GtkTreeIter iter, root; + /* A bit nasty, apologies */ + FilterTest fixture; + + /* This is a variation on the above test case wherein the has-child + * check for visibility only applies to root level nodes. + */ + + fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN); + filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL); + fixture.filter = GTK_TREE_MODEL_FILTER (filter); + fixture.monitor = NULL; + + /* We will filter on parent state using a filter function. We will + * manually keep the boolean column in sync, so that we can use + * check_filter_model() to check the consistency of the model. + */ + /* FIXME: We need a check_filter_model() that is not tied to LEVEL_LENGTH + * to be able to check the structure here. We keep the calls to + * check_filter_model() commented out until then. + */ + gtk_tree_model_filter_set_visible_func (fixture.filter, + specific_root_has_child_filter_filter_func, + NULL, NULL); + + gtk_tree_store_append (fixture.store, &root, NULL); + create_tree_store_set_values (fixture.store, &root, FALSE); + + /* check_filter_model (&fixture); */ + check_level_length (fixture.filter, NULL, 0); + + gtk_tree_store_append (fixture.store, &iter, &root); + create_tree_store_set_values (fixture.store, &iter, TRUE); + + /* Parent must now be visible. Do the level length check first, + * to avoid modifying the child model triggering a row-changed to + * the filter model. + */ + check_level_length (fixture.filter, NULL, 1); + check_level_length (fixture.filter, "0", 1); + + set_path_visibility (&fixture, "0", TRUE); + /* check_filter_model (&fixture); */ + + gtk_tree_store_append (fixture.store, &root, NULL); + check_level_length (fixture.filter, NULL, 1); + + gtk_tree_store_append (fixture.store, &iter, &root); + check_level_length (fixture.filter, NULL, 2); + check_level_length (fixture.filter, "1", 1); + + create_tree_store_set_values (fixture.store, &root, TRUE); + create_tree_store_set_values (fixture.store, &iter, TRUE); + + /* check_filter_model (&fixture); */ + + gtk_tree_store_append (fixture.store, &iter, &root); + create_tree_store_set_values (fixture.store, &iter, TRUE); + check_level_length (fixture.filter, NULL, 2); + check_level_length (fixture.filter, "0", 1); + check_level_length (fixture.filter, "1", 2); + + /* Now remove one of the remaining child rows */ + gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture.store), + &iter, "0:0"); + gtk_tree_store_remove (fixture.store, &iter); + + check_level_length (fixture.filter, NULL, 1); + check_level_length (fixture.filter, "0", 2); + + set_path_visibility (&fixture, "0", FALSE); + /* check_filter_model (&fixture); */ +} + + +static void +specific_filter_add_child (void) +{ + /* This test is based on one of the test cases I found in my + * old test cases directory. I unfortunately do not have a record + * from who this test case originated. -Kris. + */ + + GtkTreeIter iter; + GtkTreeIter iter_first; + GtkTreeIter child; + GtkTreeStore *store; + GtkTreeModel *filter; + + store = gtk_tree_store_new (1, G_TYPE_STRING); + + gtk_tree_store_append (store, &iter_first, NULL); + gtk_tree_store_set (store, &iter_first, 0, "Hello", -1); + + gtk_tree_store_append (store, &iter, NULL); + gtk_tree_store_set (store, &iter, 0, "Hello", -1); + + gtk_tree_store_append (store, &iter, NULL); + gtk_tree_store_set (store, &iter, 0, "Hello", -1); + + gtk_tree_store_append (store, &iter, NULL); + gtk_tree_store_set (store, &iter, 0, "Hello", -1); + + filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL); + + gtk_tree_store_set (store, &iter, 0, "Hello", -1); + gtk_tree_store_append (store, &child, &iter_first); + gtk_tree_store_set (store, &child, 0, "Hello", -1); +} + +static void +specific_list_store_clear (void) +{ + int i; + GtkTreeIter iter; + GtkListStore *list; + GtkTreeModel *filter; + GtkWidget *view; + + list = gtk_list_store_new (1, G_TYPE_INT); + gtk_list_store_insert_with_values (list, &iter, 0, 0, 1, -1); + gtk_list_store_insert_with_values (list, &iter, 1, 0, 2, -1); + gtk_list_store_insert_with_values (list, &iter, 2, 0, 3, -1); + gtk_list_store_insert_with_values (list, &iter, 3, 0, 4, -1); + gtk_list_store_insert_with_values (list, &iter, 4, 0, 5, -1); + gtk_list_store_insert_with_values (list, &iter, 5, 0, 6, -1); + gtk_list_store_insert_with_values (list, &iter, 6, 0, 7, -1); + gtk_list_store_insert_with_values (list, &iter, 7, 0, 8, -1); + + filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (list), NULL); + view = gtk_tree_view_new_with_model (filter); + + gtk_list_store_clear (list); +} + +static void +specific_bug_300089 (void) +{ + /* Test case for GNOME Bugzilla bug 300089. Written by + * Matthias Clasen. + */ + GtkTreeModel *sort_model, *child_model; + GtkTreePath *path; + GtkTreeIter iter, iter2, sort_iter; + + child_model = GTK_TREE_MODEL (gtk_tree_store_new (1, G_TYPE_STRING)); + + gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter, NULL); + gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter, 0, "A", -1); + gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter, NULL); + gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter, 0, "B", -1); + + gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter2, &iter); + gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter2, 0, "D", -1); + gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter2, &iter); + gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter2, 0, "E", -1); + + gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter, NULL); + gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter, 0, "C", -1); + + + sort_model = GTK_TREE_MODEL (gtk_tree_model_sort_new_with_model (child_model)); + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model), + 0, GTK_SORT_ASCENDING); + + path = gtk_tree_path_new_from_indices (1, 1, -1); + + /* make sure a level is constructed */ + gtk_tree_model_get_iter (sort_model, &sort_iter, path); + + /* change the "E" row in a way that causes it to change position */ + gtk_tree_model_get_iter (child_model, &iter, path); + gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter, 0, "A", -1); +} + + +static int +specific_bug_301558_sort_func (GtkTreeModel *model, + GtkTreeIter *a, + GtkTreeIter *b, + gpointer data) +{ + int i, j; + + gtk_tree_model_get (model, a, 0, &i, -1); + gtk_tree_model_get (model, b, 0, &j, -1); + + return j - i; +} + +static void +specific_bug_301558 (void) +{ + /* Test case for GNOME Bugzilla bug 301558 provided by + * Markku Vire. + */ + GtkTreeStore *tree; + GtkTreeModel *filter; + GtkTreeModel *sort; + GtkTreeIter root, iter, iter2; + GtkWidget *view; + int i; + gboolean add; + + tree = gtk_tree_store_new (2, G_TYPE_INT, G_TYPE_BOOLEAN); + gtk_tree_store_append (tree, &iter, NULL); + gtk_tree_store_set (tree, &iter, 0, 123, 1, TRUE, -1); + gtk_tree_store_append (tree, &iter2, &iter); + gtk_tree_store_set (tree, &iter2, 0, 73, 1, TRUE, -1); + + sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (tree)); + gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (sort), + specific_bug_301558_sort_func, + NULL, NULL); + + filter = gtk_tree_model_filter_new (sort, NULL); + gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER (filter), 1); + + view = gtk_tree_view_new_with_model (filter); + + while (gtk_events_pending ()) + gtk_main_iteration (); + + add = TRUE; + + for (i = 0; i < 10; i++) + { + if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (tree), &root)) + g_assert_not_reached (); + + if (add) + { + gtk_tree_store_append (tree, &iter, &root); + gtk_tree_store_set (tree, &iter, 0, 456, 1, TRUE, -1); + } + else + { + int n; + n = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (tree), &root); + gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (tree), &iter, + &root, n - 1); + gtk_tree_store_remove (tree, &iter); + } + + add = !add; + } +} + + +static gboolean +specific_bug_311955_filter_func (GtkTreeModel *model, + GtkTreeIter *iter, + gpointer data) +{ + int value; + + gtk_tree_model_get (model, iter, 0, &value, -1); + + return (value != 0); +} + +static void +specific_bug_311955 (void) +{ + /* This is a test case for GNOME Bugzilla bug 311955. It was written + * by Markku Vire. + */ + GtkTreeIter iter, child, root; + GtkTreeStore *store; + GtkTreeModel *sort; + GtkTreeModel *filter; + + GtkWidget *window; + GtkWidget *tree_view; + int i; + int n; + + store = gtk_tree_store_new (1, G_TYPE_INT); + + gtk_tree_store_append (store, &root, NULL); + gtk_tree_store_set (store, &root, 0, 33, -1); + + gtk_tree_store_append (store, &iter, &root); + gtk_tree_store_set (store, &iter, 0, 50, -1); + + gtk_tree_store_append (store, &iter, NULL); + gtk_tree_store_set (store, &iter, 0, 22, -1); + + sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store)); + filter = gtk_tree_model_filter_new (sort, NULL); + + gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter), + specific_bug_311955_filter_func, + NULL, NULL); + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + tree_view = gtk_tree_view_new_with_model (filter); + g_object_unref (store); + + gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view)); + + while (gtk_events_pending ()) + gtk_main_iteration (); + + /* Fill model */ + for (i = 0; i < 4; i++) + { + gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &root); + + gtk_tree_store_append (store, &iter, &root); + + if (i < 3) + gtk_tree_store_set (store, &iter, 0, i, -1); + + if (i % 2 == 0) + { + gtk_tree_store_append (store, &child, &iter); + gtk_tree_store_set (store, &child, 0, 10, -1); + } + } + + while (gtk_events_pending ()) + gtk_main_iteration (); + + /* Remove bottommost child from the tree. */ + gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &root); + n = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), &root); + + if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter, &root, n - 2)) + { + if (gtk_tree_model_iter_children (GTK_TREE_MODEL (store), &child, &iter)) + gtk_tree_store_remove (store, &child); + } + else + g_assert_not_reached (); +} + +static void +specific_bug_346800 (void) +{ + /* This is a test case for GNOME Bugzilla bug 346800. It was written + * by Jonathan Matthew. + */ + + GtkTreeIter node_iters[50]; + GtkTreeIter child_iters[50]; + GtkTreeModel *model; + GtkTreeModelFilter *filter; + GtkTreeStore *store; + GType *columns; + int i; + int items = 50; + columns = g_new (GType, 2); + columns[0] = G_TYPE_STRING; + columns[1] = G_TYPE_BOOLEAN; + store = gtk_tree_store_newv (2, columns); + model = GTK_TREE_MODEL (store); + + filter = GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (model, NULL)); + gtk_tree_model_filter_set_visible_column (filter, 1); + + for (i=0; i 6) + { + gtk_tree_store_set (GTK_TREE_STORE (model), &child_iters[i-1], 1, + (i & 1) ? TRUE : FALSE, -1); + gtk_tree_model_filter_refilter (filter); + + gtk_tree_store_set (GTK_TREE_STORE (model), &child_iters[i-2], 1, + (i & 1) ? FALSE: TRUE, -1); + gtk_tree_model_filter_refilter (filter); + } + } +} + + +static void +specific_bug_364946 (void) +{ + /* This is a test case for GNOME Bugzilla bug 364946. It was written + * by Andreas Koehler. + */ + GtkTreeStore *store; + GtkTreeIter a, aa, aaa, aab, iter; + GtkTreeModel *s_model; + + store = gtk_tree_store_new (1, G_TYPE_STRING); + + gtk_tree_store_append (store, &a, NULL); + gtk_tree_store_set (store, &a, 0, "0", -1); + + gtk_tree_store_append (store, &aa, &a); + gtk_tree_store_set (store, &aa, 0, "0:0", -1); + + gtk_tree_store_append (store, &aaa, &aa); + gtk_tree_store_set (store, &aaa, 0, "0:0:0", -1); + + gtk_tree_store_append (store, &aab, &aa); + gtk_tree_store_set (store, &aab, 0, "0:0:1", -1); + + s_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store)); + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (s_model), 0, + GTK_SORT_ASCENDING); + + gtk_tree_model_get_iter_from_string (s_model, &iter, "0:0:0"); + + gtk_tree_store_set (store, &aaa, 0, "0:0:0", -1); + gtk_tree_store_remove (store, &aaa); + gtk_tree_store_remove (store, &aab); + + gtk_tree_model_sort_clear_cache (GTK_TREE_MODEL_SORT (s_model)); +} + + +static gboolean +specific_bug_464173_visible_func (GtkTreeModel *model, + GtkTreeIter *iter, + gpointer data) +{ + gboolean *visible = (gboolean *)data; + + return *visible; +} + +static void +specific_bug_464173 (void) +{ + /* Test case for GNOME Bugzilla bug 464173, test case written + * by Andreas Koehler. + */ + GtkTreeStore *model; + GtkTreeModelFilter *f_model; + GtkTreeIter iter1, iter2; + GtkWidget *view; + gboolean visible = TRUE; + + model = gtk_tree_store_new (1, G_TYPE_STRING); + gtk_tree_store_append (model, &iter1, NULL); + gtk_tree_store_set (model, &iter1, 0, "Foo", -1); + gtk_tree_store_append (model, &iter2, &iter1); + gtk_tree_store_set (model, &iter2, 0, "Bar", -1); + + f_model = GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (GTK_TREE_MODEL(model), NULL)); + gtk_tree_model_filter_set_visible_func (f_model, + specific_bug_464173_visible_func, + &visible, NULL); + + view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (f_model)); + + visible = FALSE; + gtk_tree_model_filter_refilter (f_model); +} + + +static gboolean +specific_bug_540201_filter_func (GtkTreeModel *model, + GtkTreeIter *iter, + gpointer data) +{ + gboolean has_children; + + has_children = gtk_tree_model_iter_has_child (model, iter); + + return has_children; +} + +static void +specific_bug_540201 (void) +{ + /* Test case for GNOME Bugzilla bug 540201, steps provided by + * Charles Day. + */ + GtkTreeIter iter, root; + GtkTreeStore *store; + GtkTreeModel *filter; + + GtkWidget *tree_view; + + store = gtk_tree_store_new (1, G_TYPE_INT); + + gtk_tree_store_append (store, &root, NULL); + gtk_tree_store_set (store, &root, 0, 33, -1); + + filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL); + tree_view = gtk_tree_view_new_with_model (filter); + + gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter), + specific_bug_540201_filter_func, + NULL, NULL); + + gtk_tree_store_append (store, &iter, &root); + gtk_tree_store_set (store, &iter, 0, 50, -1); + + gtk_tree_store_append (store, &iter, &root); + gtk_tree_store_set (store, &iter, 0, 22, -1); + + + gtk_tree_store_append (store, &root, NULL); + gtk_tree_store_set (store, &root, 0, 33, -1); + + gtk_tree_store_append (store, &iter, &root); + gtk_tree_store_set (store, &iter, 0, 22, -1); +} + + +static gboolean +specific_bug_549287_visible_func (GtkTreeModel *model, + GtkTreeIter *iter, + gpointer data) +{ + gboolean result = FALSE; + + result = gtk_tree_model_iter_has_child (model, iter); + + return result; +} + +static void +specific_bug_549287 (void) +{ + /* Test case for GNOME Bugzilla bug 529287, provided by Julient Puydt */ + + int i; + GtkTreeStore *store; + GtkTreeModel *filtered; + GtkWidget *view; + GtkTreeIter iter; + GtkTreeIter *swap, *parent, *child; + + store = gtk_tree_store_new (1, G_TYPE_STRING); + filtered = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL); + gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filtered), + specific_bug_549287_visible_func, + NULL, NULL); + + view = gtk_tree_view_new_with_model (filtered); + + for (i = 0; i < 4; i++) + { + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) + { + parent = gtk_tree_iter_copy (&iter); + child = gtk_tree_iter_copy (&iter); + + while (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), + child, parent, 0)) + { + + swap = parent; + parent = child; + child = swap; + } + + gtk_tree_store_append (store, child, parent); + gtk_tree_store_set (store, child, + 0, "Something", + -1); + + gtk_tree_iter_free (parent); + gtk_tree_iter_free (child); + } + else + { + gtk_tree_store_append (store, &iter, NULL); + gtk_tree_store_set (store, &iter, + 0, "Something", + -1); + } + + /* since we inserted something, we changed the visibility conditions: */ + gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (filtered)); + } +} + +/* main */ + +int +main (int argc, + char **argv) +{ + gtk_test_init (&argc, &argv, NULL); + + g_test_add ("/FilterModel/self/verify-test-suite", + FilterTest, NULL, + filter_test_setup, + verify_test_suite, + filter_test_teardown); + + g_test_add ("/FilterModel/self/verify-test-suite/vroot/depth-1", + FilterTest, gtk_tree_path_new_from_indices (2, -1), + filter_test_setup, + verify_test_suite_vroot, + filter_test_teardown); + g_test_add ("/FilterModel/self/verify-test-suite/vroot/depth-2", + FilterTest, gtk_tree_path_new_from_indices (2, 3, -1), + filter_test_setup, + verify_test_suite_vroot, + filter_test_teardown); + + + g_test_add ("/FilterModel/filled/hide-root-level", + FilterTest, NULL, + filter_test_setup, + filled_hide_root_level, + filter_test_teardown); + g_test_add ("/FilterModel/filled/hide-child-levels", + FilterTest, NULL, + filter_test_setup, + filled_hide_child_levels, + filter_test_teardown); + + g_test_add ("/FilterModel/filled/hide-root-level/vroot", + FilterTest, gtk_tree_path_new_from_indices (2, -1), + filter_test_setup, + filled_vroot_hide_root_level, + filter_test_teardown); + g_test_add ("/FilterModel/filled/hide-child-levels/vroot", + FilterTest, gtk_tree_path_new_from_indices (2, -1), + filter_test_setup, + filled_vroot_hide_child_levels, + filter_test_teardown); + + + g_test_add ("/FilterModel/empty/show-nodes", + FilterTest, NULL, + filter_test_setup_empty, + empty_show_nodes, + filter_test_teardown); + g_test_add ("/FilterModel/empty/show-multiple-nodes", + FilterTest, NULL, + filter_test_setup_empty, + empty_show_multiple_nodes, + filter_test_teardown); + + g_test_add ("/FilterModel/empty/show-nodes/vroot", + FilterTest, gtk_tree_path_new_from_indices (2, -1), + filter_test_setup_empty, + empty_vroot_show_nodes, + filter_test_teardown); + g_test_add ("/FilterModel/empty/show-multiple-nodes/vroot", + FilterTest, gtk_tree_path_new_from_indices (2, -1), + filter_test_setup_empty, + empty_vroot_show_multiple_nodes, + filter_test_teardown); + + + g_test_add ("/FilterModel/unfiltered/hide-single", + FilterTest, NULL, + filter_test_setup_unfiltered, + unfiltered_hide_single, + filter_test_teardown); + g_test_add ("/FilterModel/unfiltered/hide-single-child", + FilterTest, NULL, + filter_test_setup_unfiltered, + unfiltered_hide_single_child, + filter_test_teardown); + g_test_add ("/FilterModel/unfiltered/hide-single-multi-level", + FilterTest, NULL, + filter_test_setup_unfiltered, + unfiltered_hide_single_multi_level, + filter_test_teardown); + + g_test_add ("/FilterModel/unfiltered/hide-single/vroot", + FilterTest, gtk_tree_path_new_from_indices (2, -1), + filter_test_setup_unfiltered, + unfiltered_vroot_hide_single, + filter_test_teardown); + g_test_add ("/FilterModel/unfiltered/hide-single-child/vroot", + FilterTest, gtk_tree_path_new_from_indices (2, -1), + filter_test_setup_unfiltered, + unfiltered_vroot_hide_single_child, + filter_test_teardown); + g_test_add ("/FilterModel/unfiltered/hide-single-multi-level/vroot", + FilterTest, gtk_tree_path_new_from_indices (2, -1), + filter_test_setup_unfiltered, + unfiltered_vroot_hide_single_multi_level, + filter_test_teardown); + + + + g_test_add ("/FilterModel/unfiltered/show-single", + FilterTest, NULL, + filter_test_setup_empty_unfiltered, + unfiltered_show_single, + filter_test_teardown); + g_test_add ("/FilterModel/unfiltered/show-single-child", + FilterTest, NULL, + filter_test_setup_empty_unfiltered, + unfiltered_show_single_child, + filter_test_teardown); + g_test_add ("/FilterModel/unfiltered/show-single-multi-level", + FilterTest, NULL, + filter_test_setup_empty_unfiltered, + unfiltered_show_single_multi_level, + filter_test_teardown); + + g_test_add ("/FilterModel/unfiltered/show-single/vroot", + FilterTest, gtk_tree_path_new_from_indices (2, -1), + filter_test_setup_empty_unfiltered, + unfiltered_vroot_show_single, + filter_test_teardown); + g_test_add ("/FilterModel/unfiltered/show-single-child/vroot", + FilterTest, gtk_tree_path_new_from_indices (2, -1), + filter_test_setup_empty_unfiltered, + unfiltered_vroot_show_single_child, + filter_test_teardown); + g_test_add ("/FilterModel/unfiltered/show-single-multi-level/vroot", + FilterTest, gtk_tree_path_new_from_indices (2, -1), + filter_test_setup_empty_unfiltered, + unfiltered_vroot_show_single_multi_level, + filter_test_teardown); + + + g_test_add_func ("/FilterModel/specific/path-dependent-filter", + specific_path_dependent_filter); + g_test_add_func ("/FilterModel/specific/append-after-collapse", + specific_append_after_collapse); + g_test_add_func ("/FilterModel/specific/sort-filter-remove-node", + specific_sort_filter_remove_node); + g_test_add_func ("/FilterModel/specific/sort-filter-remove-root", + specific_sort_filter_remove_root); + g_test_add_func ("/FilterModel/specific/root-mixed-visibility", + specific_root_mixed_visibility); + g_test_add_func ("/FilterModel/specific/has-child-filter", + specific_has_child_filter); + g_test_add_func ("/FilterModel/specific/root-has-child-filter", + specific_root_has_child_filter); + g_test_add_func ("/FilterModel/specific/filter-add-child", + specific_filter_add_child); + g_test_add_func ("/FilterModel/specific/list-store-clear", + specific_list_store_clear); + + g_test_add_func ("/FilterModel/specific/bug-300089", + specific_bug_300089); + g_test_add_func ("/FilterModel/specific/bug-301558", + specific_bug_301558); + g_test_add_func ("/FilterModel/specific/bug-311955", + specific_bug_311955); + g_test_add_func ("/FilterModel/specific/bug-346800", + specific_bug_346800); + g_test_add_func ("/FilterModel/specific/bug-364946", + specific_bug_364946); + g_test_add_func ("/FilterModel/specific/bug-464173", + specific_bug_464173); + g_test_add_func ("/FilterModel/specific/bug-540201", + specific_bug_540201); + g_test_add_func ("/FilterModel/specific/bug-549287", + specific_bug_549287); + + return g_test_run (); +} diff --git a/gtk/tests/liststore.c b/gtk/tests/liststore.c index 588f725f3d..6452fc2903 100644 --- a/gtk/tests/liststore.c +++ b/gtk/tests/liststore.c @@ -850,6 +850,72 @@ list_store_test_move_before_single (void) g_object_unref (store); } + +/* iter invalidation */ + +static void +list_store_test_iter_next_invalid (ListStore *fixture, + gconstpointer user_data) +{ + GtkTreePath *path; + GtkTreeIter iter; + + path = gtk_tree_path_new_from_indices (4, -1); + gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &iter, path); + gtk_tree_path_free (path); + + g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), + &iter) == FALSE); + g_assert (gtk_list_store_iter_is_valid (fixture->store, &iter) == FALSE); + g_assert (iter.stamp == 0); +} + +static void +list_store_test_iter_children_invalid (ListStore *fixture, + gconstpointer user_data) +{ + GtkTreeIter iter, child; + + gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), &iter); + g_assert (gtk_list_store_iter_is_valid (fixture->store, &iter) == TRUE); + + g_assert (gtk_tree_model_iter_children (GTK_TREE_MODEL (fixture->store), + &child, &iter) == FALSE); + g_assert (gtk_list_store_iter_is_valid (fixture->store, &child) == FALSE); + g_assert (child.stamp == 0); +} + +static void +list_store_test_iter_nth_child_invalid (ListStore *fixture, + gconstpointer user_data) +{ + GtkTreeIter iter, child; + + gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), &iter); + g_assert (gtk_list_store_iter_is_valid (fixture->store, &iter) == TRUE); + + g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (fixture->store), + &child, &iter, 0) == FALSE); + g_assert (gtk_list_store_iter_is_valid (fixture->store, &child) == FALSE); + g_assert (child.stamp == 0); +} + +static void +list_store_test_iter_parent_invalid (ListStore *fixture, + gconstpointer user_data) +{ + GtkTreeIter iter, child; + + gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), &child); + g_assert (gtk_list_store_iter_is_valid (fixture->store, &child) == TRUE); + + g_assert (gtk_tree_model_iter_parent (GTK_TREE_MODEL (fixture->store), + &iter, &child) == FALSE); + g_assert (gtk_list_store_iter_is_valid (fixture->store, &iter) == FALSE); + g_assert (iter.stamp == 0); +} + + /* main */ int @@ -958,5 +1024,19 @@ main (int argc, g_test_add_func ("/list-store/move-before-single", list_store_test_move_before_single); + /* iter invalidation */ + g_test_add ("/list-store/iter-next-invalid", ListStore, NULL, + list_store_setup, list_store_test_iter_next_invalid, + list_store_teardown); + g_test_add ("/list-store/iter-children-invalid", ListStore, NULL, + list_store_setup, list_store_test_iter_children_invalid, + list_store_teardown); + g_test_add ("/list-store/iter-nth-child-invalid", ListStore, NULL, + list_store_setup, list_store_test_iter_nth_child_invalid, + list_store_teardown); + g_test_add ("/list-store/iter-parent-invalid", ListStore, NULL, + list_store_setup, list_store_test_iter_parent_invalid, + list_store_teardown); + return g_test_run (); } diff --git a/gtk/tests/testing.c b/gtk/tests/testing.c index a7b43d5bd4..8feb71bfd4 100644 --- a/gtk/tests/testing.c +++ b/gtk/tests/testing.c @@ -38,9 +38,13 @@ test_button_clicks (void) g_assert (button != NULL); simsuccess = gtk_test_widget_click (button, 1, 0); g_assert (simsuccess == TRUE); - while (gtk_events_pending ()) + while (gtk_events_pending ()) { + g_print ("iterate main loop\n"); gtk_main_iteration (); - g_assert (a == 0 && b > 0 && c == 0); + } + g_assert (a == 0); + g_assert (b > 0); + g_assert (c == 0); } static void @@ -62,7 +66,9 @@ test_button_keys (void) g_assert (simsuccess == TRUE); while (gtk_events_pending ()) gtk_main_iteration (); - g_assert (a == 0 && b > 0 && c == 0); + g_assert (a == 0); + g_assert (b > 0); + g_assert (c == 0); } static void diff --git a/gtk/tests/textbuffer.c b/gtk/tests/textbuffer.c index 822b04c752..010776d478 100644 --- a/gtk/tests/textbuffer.c +++ b/gtk/tests/textbuffer.c @@ -879,6 +879,8 @@ split_r_n_separators_test (void) gtk_text_buffer_get_iter_at_offset (buffer, &iter, 3); g_assert (gtk_text_iter_ends_line (&iter)); + + g_object_unref (buffer); } static void @@ -912,6 +914,40 @@ test_line_separator (void) split_r_n_separators_test (); } +static void +test_backspace (void) +{ + GtkTextBuffer *buffer; + GtkTextIter iter; + gboolean ret; + + buffer = gtk_text_buffer_new (NULL); + + gtk_text_buffer_set_text (buffer, "foo", -1); + gtk_text_buffer_get_iter_at_offset (buffer, &iter, 2); + ret = gtk_text_buffer_backspace (buffer, &iter, TRUE, TRUE); + g_assert (ret); + g_assert_cmpint (1, ==, gtk_text_iter_get_offset (&iter)); + g_assert_cmpint (2, ==, gtk_text_buffer_get_char_count (buffer)); + + gtk_text_buffer_set_text (buffer, "foo", -1); + gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0); + ret = gtk_text_buffer_backspace (buffer, &iter, TRUE, TRUE); + g_assert (!ret); + g_assert_cmpint (0, ==, gtk_text_iter_get_offset (&iter)); + g_assert_cmpint (3, ==, gtk_text_buffer_get_char_count (buffer)); + + /* test bug #544724 */ + gtk_text_buffer_set_text (buffer, "foo\r\n\r\nbar", -1); + gtk_text_buffer_get_iter_at_offset (buffer, &iter, 5); + ret = gtk_text_buffer_backspace (buffer, &iter, TRUE, TRUE); + g_assert (ret); + g_assert_cmpint (0, ==, gtk_text_iter_get_line (&iter)); + g_assert_cmpint (8, ==, gtk_text_buffer_get_char_count (buffer)); + + g_object_unref (buffer); +} + static void test_logical_motion (void) { @@ -1297,6 +1333,7 @@ main (int argc, char** argv) g_test_add_func ("/TextBuffer/UTF8 unknown char", test_utf8); g_test_add_func ("/TextBuffer/Line separator", test_line_separator); + g_test_add_func ("/TextBuffer/Backspace", test_backspace); g_test_add_func ("/TextBuffer/Logical motion", test_logical_motion); g_test_add_func ("/TextBuffer/Marks", test_marks); g_test_add_func ("/TextBuffer/Empty buffer", test_empty_buffer); diff --git a/gtk/tests/treestore.c b/gtk/tests/treestore.c index e3a85c92fe..c9dbcffba8 100644 --- a/gtk/tests/treestore.c +++ b/gtk/tests/treestore.c @@ -853,6 +853,72 @@ tree_store_test_move_before_single (void) g_object_unref (store); } + +/* iter invalidation */ + +static void +tree_store_test_iter_next_invalid (TreeStore *fixture, + gconstpointer user_data) +{ + GtkTreePath *path; + GtkTreeIter iter; + + path = gtk_tree_path_new_from_indices (4, -1); + gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &iter, path); + gtk_tree_path_free (path); + + g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), + &iter) == FALSE); + g_assert (gtk_tree_store_iter_is_valid (fixture->store, &iter) == FALSE); + g_assert (iter.stamp == 0); +} + +static void +tree_store_test_iter_children_invalid (TreeStore *fixture, + gconstpointer user_data) +{ + GtkTreeIter iter, child; + + gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), &iter); + g_assert (gtk_tree_store_iter_is_valid (fixture->store, &iter) == TRUE); + + g_assert (gtk_tree_model_iter_children (GTK_TREE_MODEL (fixture->store), + &child, &iter) == FALSE); + g_assert (gtk_tree_store_iter_is_valid (fixture->store, &child) == FALSE); + g_assert (child.stamp == 0); +} + +static void +tree_store_test_iter_nth_child_invalid (TreeStore *fixture, + gconstpointer user_data) +{ + GtkTreeIter iter, child; + + gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), &iter); + g_assert (gtk_tree_store_iter_is_valid (fixture->store, &iter) == TRUE); + + g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (fixture->store), + &child, &iter, 0) == FALSE); + g_assert (gtk_tree_store_iter_is_valid (fixture->store, &child) == FALSE); + g_assert (child.stamp == 0); +} + +static void +tree_store_test_iter_parent_invalid (TreeStore *fixture, + gconstpointer user_data) +{ + GtkTreeIter iter, child; + + gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), &child); + g_assert (gtk_tree_store_iter_is_valid (fixture->store, &child) == TRUE); + + g_assert (gtk_tree_model_iter_parent (GTK_TREE_MODEL (fixture->store), + &iter, &child) == FALSE); + g_assert (gtk_tree_store_iter_is_valid (fixture->store, &iter) == FALSE); + g_assert (iter.stamp == 0); +} + + /* main */ int @@ -961,5 +1027,19 @@ main (int argc, g_test_add_func ("/tree-store/move-before-single", tree_store_test_move_before_single); + /* iter invalidation */ + g_test_add ("/tree-store/iter-next-invalid", TreeStore, NULL, + tree_store_setup, tree_store_test_iter_next_invalid, + tree_store_teardown); + g_test_add ("/tree-store/iter-children-invalid", TreeStore, NULL, + tree_store_setup, tree_store_test_iter_children_invalid, + tree_store_teardown); + g_test_add ("/tree-store/iter-nth-child-invalid", TreeStore, NULL, + tree_store_setup, tree_store_test_iter_nth_child_invalid, + tree_store_teardown); + g_test_add ("/tree-store/iter-parent-invalid", TreeStore, NULL, + tree_store_setup, tree_store_test_iter_parent_invalid, + tree_store_teardown); + return g_test_run (); } diff --git a/gtk/tests/treeview-scrolling.c b/gtk/tests/treeview-scrolling.c index 0207dbcff2..81dfd8d752 100644 --- a/gtk/tests/treeview-scrolling.c +++ b/gtk/tests/treeview-scrolling.c @@ -1,6 +1,7 @@ /* Scrolling test suite for GtkTreeView * Copyright (C) 2006 Kristian Rietveld * Copyright (C) 2007 Imendio AB, Kristian Rietveld + * Copyright (C) 2009 Kristian Rietveld * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -37,6 +38,8 @@ * - Test that nothing happens if the row is fully visible. * - The tests are dependent on the theme/font (size measurements, * chosen paths). + * - Convert to proper GTK+ coding style. + * - Briefly test scrolling in tree stores as well. */ @@ -175,6 +178,34 @@ scroll_fixture_single_setup (ScrollFixture *fixture, scroll_fixture_setup (fixture, GTK_TREE_MODEL (store), test_data); } +/* sets up a fixture with a tree store */ +static void +scroll_fixture_tree_setup (ScrollFixture *fixture, + gconstpointer test_data) +{ + GtkTreeStore *store; + GtkTreeIter iter, child; + int i; + + store = gtk_tree_store_new (1, G_TYPE_STRING); + + gtk_tree_store_append (store, &iter, NULL); + gtk_tree_store_set (store, &iter, 0, "Root node", -1); + + for (i = 0; i < 5; i++) { + gtk_tree_store_append (store, &child, &iter); + gtk_tree_store_set (store, &child, 0, "Child node", -1); + } + + for (i = 0; i < 5; i++) { + gtk_tree_store_append (store, &iter, NULL); + gtk_tree_store_set (store, &iter, 0, "Other node", -1); + } + + /* The teardown will also destroy the model */ + scroll_fixture_setup (fixture, GTK_TREE_MODEL (store), test_data); +} + static void scroll_fixture_teardown (ScrollFixture *fixture, gconstpointer test_data) @@ -752,6 +783,56 @@ scroll_new_row (ScrollFixture *fixture, gtk_tree_path_free (scroll_path); } +static void +scroll_new_row_tree (ScrollFixture *fixture, + gconstpointer test_data) +{ + GtkTreeModel *model; + GtkAdjustment *vadjustment; + int i; + + /* The goal of this test is to append new rows at the end of a tree + * store and immediately scroll to them. If there is a parent + * node with a couple of childs in the "area above" to explore, + * this used to lead to unexpected results due to a bug. + * + * This issue has been reported by Miroslav Rajcic on + * gtk-app-devel-list: + * http://mail.gnome.org/archives/gtk-app-devel-list/2008-December/msg00068.html + */ + + gtk_widget_show_all (fixture->window); + + gtk_tree_view_expand_all (GTK_TREE_VIEW (fixture->tree_view)); + + while (gtk_events_pending ()) + gtk_main_iteration (); + + model = gtk_tree_view_get_model (GTK_TREE_VIEW (fixture->tree_view)); + vadjustment = gtk_tree_view_get_vadjustment (GTK_TREE_VIEW (fixture->tree_view)); + + for (i = 0; i < 5; i++) { + GtkTreeIter scroll_iter; + GtkTreePath *scroll_path; + + gtk_tree_store_append (GTK_TREE_STORE (model), &scroll_iter, + NULL); + gtk_tree_store_set (GTK_TREE_STORE (model), &scroll_iter, + 0, "New node", -1); + + scroll_path = gtk_tree_model_get_path (model, &scroll_iter); + gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (fixture->tree_view), + scroll_path, NULL, FALSE, 0.0, 0.0); + gtk_tree_path_free (scroll_path); + + while (gtk_events_pending ()) + gtk_main_iteration (); + + /* Test position, the scroll bar must be at the end */ + g_assert (vadjustment->value == vadjustment->upper - vadjustment->page_size); + } +} + /* Test for GNOME bugzilla bug 359231; tests "recovery when removing a bunch of * rows at the bottom. */ @@ -874,10 +955,10 @@ test_type_string (int test_type) { switch (test_type) { case BEFORE: - return "before"; + return "before-realize"; case AFTER: - return "after"; + return "after-realize"; case BOTH: return "both"; @@ -913,7 +994,7 @@ add_test (const char *path, align = align_string (use_align, row_align); - test_path = g_strdup_printf ("/treeview/scrolling/%s-%s-path-%s-%s", + test_path = g_strdup_printf ("/TreeView/scrolling/%s/%s-height/path-%s-%s", test_type_string (test_type), mixed ? "mixed" : "constant", path, align); @@ -1013,42 +1094,46 @@ main (int argc, char **argv) } /* Test different alignments in view with single row */ - g_test_add ("/treeview/scrolling/single-no-align", ScrollFixture, "0", + g_test_add ("/TreeView/scrolling/single-row/no-align", + ScrollFixture, "0", scroll_fixture_single_setup, scroll_no_align, scroll_fixture_teardown); - g_test_add ("/treeview/scrolling/single-align-0.0", ScrollFixture, "0", + g_test_add ("/TreeView/scrolling/single-row/align-0.0", + ScrollFixture, "0", scroll_fixture_single_setup, scroll_align_0_0, scroll_fixture_teardown); - g_test_add ("/treeview/scrolling/single-align-0.5", ScrollFixture, "0", + g_test_add ("/TreeView/scrolling/single-row/align-0.5", + ScrollFixture, "0", scroll_fixture_single_setup, scroll_align_0_5, scroll_fixture_teardown); - g_test_add ("/treeview/scrolling/single-align-1.0", ScrollFixture, "0", + g_test_add ("/TreeView/scrolling/single-row/align-1.0", + ScrollFixture, "0", scroll_fixture_single_setup, scroll_align_1_0, scroll_fixture_teardown); /* Test scrolling in a very large model; also very slow */ if (g_test_slow ()) { - g_test_add ("/treeview/scrolling/constant-big-middle-no-align", + g_test_add ("/TreeView/scrolling/large-model/constant-height/middle-no-align", ScrollFixture, "50000", scroll_fixture_constant_big_setup, scroll_no_align, scroll_fixture_teardown); - g_test_add ("/treeview/scrolling/constant-big-end-no-align", + g_test_add ("/TreeView/scrolling/large-model/constant-height/end-no-align", ScrollFixture, "99999", scroll_fixture_constant_big_setup, scroll_no_align, scroll_fixture_teardown); - g_test_add ("/treeview/scrolling/mixed-big-middle-no-align", + g_test_add ("/TreeView/scrolling/large-model/mixed-height/middle-no-align", ScrollFixture, "50000", scroll_fixture_mixed_big_setup, scroll_no_align, scroll_fixture_teardown); - g_test_add ("/treeview/scrolling/mixed-big-end-no-align", + g_test_add ("/TreeView/scrolling/large-model/mixed-height/end-no-align", ScrollFixture, "99999", scroll_fixture_mixed_big_setup, scroll_no_align, @@ -1056,12 +1141,12 @@ main (int argc, char **argv) } /* Test scrolling to a newly created row */ - g_test_add ("/treeview/scrolling/new-row-path-0", ScrollFixture, + g_test_add ("/TreeView/scrolling/new-row/path-0", ScrollFixture, GINT_TO_POINTER (0), scroll_fixture_constant_setup, scroll_new_row, scroll_fixture_teardown); - g_test_add ("/treeview/scrolling/new-row-path-4", ScrollFixture, + g_test_add ("/TreeView/scrolling/new-row/path-4", ScrollFixture, GINT_TO_POINTER (4), scroll_fixture_constant_setup, scroll_new_row, @@ -1070,27 +1155,35 @@ main (int argc, char **argv) * based on my font setting of "Vera Sans 11" and * the separators set to 0. (This should be made dynamic; FIXME). */ - g_test_add ("/treeview/scrolling/new-row-path-8", ScrollFixture, + g_test_add ("/TreeView/scrolling/new-row/path-8", ScrollFixture, GINT_TO_POINTER (8), scroll_fixture_constant_setup, scroll_new_row, scroll_fixture_teardown); - g_test_add ("/treeview/scrolling/new-row-path-500", ScrollFixture, + g_test_add ("/TreeView/scrolling/new-row/path-500", ScrollFixture, GINT_TO_POINTER (500), scroll_fixture_constant_setup, scroll_new_row, scroll_fixture_teardown); - g_test_add ("/treeview/scrolling/new-row-path-999", ScrollFixture, + g_test_add ("/TreeView/scrolling/new-row/path-999", ScrollFixture, GINT_TO_POINTER (999), scroll_fixture_constant_setup, scroll_new_row, scroll_fixture_teardown); + g_test_add ("/TreeView/scrolling/new-row/tree", ScrollFixture, + NULL, + scroll_fixture_tree_setup, + scroll_new_row_tree, + scroll_fixture_teardown); + /* Misc. tests */ - g_test_add ("/treeview/scrolling/bug-316689", ScrollFixture, NULL, + g_test_add ("/TreeView/scrolling/specific/bug-316689", + ScrollFixture, NULL, scroll_fixture_constant_setup, test_bug316689, scroll_fixture_teardown); - g_test_add_func ("/treeview/scrolling/bug-359231", test_bug359231); + g_test_add_func ("/TreeView/scrolling/specific/bug-359231", + test_bug359231); return g_test_run (); } diff --git a/gtk/tests/treeview.c b/gtk/tests/treeview.c new file mode 100644 index 0000000000..3dcc44287f --- /dev/null +++ b/gtk/tests/treeview.c @@ -0,0 +1,165 @@ +/* Basic GtkTreeView unit tests. + * Copyright (C) 2009 Kristian Rietveld + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include + +static void +test_bug_546005 (void) +{ + GtkTreeIter iter; + GtkTreePath *path; + GtkTreePath *cursor_path; + GtkListStore *list_store; + GtkWidget *view; + + /* Tests provided by Bjorn Lindqvist, Paul Pogonyshev */ + view = gtk_tree_view_new (); + + /* Invalid path on tree view without model */ + path = gtk_tree_path_new_from_indices (1, -1); + gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path, + NULL, FALSE); + gtk_tree_path_free (path); + + list_store = gtk_list_store_new (1, G_TYPE_STRING); + gtk_tree_view_set_model (GTK_TREE_VIEW (view), + GTK_TREE_MODEL (list_store)); + + /* Invalid path on tree view with empty model */ + path = gtk_tree_path_new_from_indices (1, -1); + gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path, + NULL, FALSE); + gtk_tree_path_free (path); + + /* Valid path */ + gtk_list_store_insert_with_values (list_store, &iter, 0, + 0, "hi", + -1); + + path = gtk_tree_path_new_from_indices (0, -1); + gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path, + NULL, FALSE); + + gtk_tree_view_get_cursor (GTK_TREE_VIEW (view), &cursor_path, NULL); + g_assert (gtk_tree_path_compare (cursor_path, path) == 0); + + gtk_tree_path_free (path); + gtk_tree_path_free (cursor_path); + + /* Invalid path on tree view with model */ + path = gtk_tree_path_new_from_indices (1, -1); + gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path, + NULL, FALSE); + gtk_tree_path_free (path); +} + +static void +test_bug_539377 (void) +{ + GtkWidget *view; + GtkTreePath *path; + GtkListStore *list_store; + + /* Test provided by Bjorn Lindqvist */ + + /* Non-realized view, no model */ + view = gtk_tree_view_new (); + g_assert (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (view), 10, 10, &path, + NULL, NULL, NULL) == FALSE); + g_assert (gtk_tree_view_get_dest_row_at_pos (GTK_TREE_VIEW (view), 10, 10, + &path, NULL) == FALSE); + + /* Non-realized view, with model */ + list_store = gtk_list_store_new (1, G_TYPE_STRING); + gtk_tree_view_set_model (GTK_TREE_VIEW (view), + GTK_TREE_MODEL (list_store)); + + g_assert (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (view), 10, 10, &path, + NULL, NULL, NULL) == FALSE); + g_assert (gtk_tree_view_get_dest_row_at_pos (GTK_TREE_VIEW (view), 10, 10, + &path, NULL) == FALSE); +} + +static void +test_select_collapsed_row (void) +{ + GtkTreeIter child, parent; + GtkTreePath *path; + GtkTreeStore *tree_store; + GtkTreeSelection *selection; + GtkWidget *view; + + /* Reported by Michael Natterer */ + tree_store = gtk_tree_store_new (1, G_TYPE_STRING); + view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (tree_store)); + + gtk_tree_store_insert_with_values (tree_store, &parent, NULL, 0, + 0, "Parent", + -1); + + gtk_tree_store_insert_with_values (tree_store, &child, &parent, 0, + 0, "Child", + -1); + gtk_tree_store_insert_with_values (tree_store, &child, &parent, 0, + 0, "Child", + -1); + + + /* Try to select a child path. */ + path = gtk_tree_path_new_from_indices (0, 1, -1); + gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path, NULL, FALSE); + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view)); + + /* Check that the parent is not selected. */ + gtk_tree_path_up (path); + g_return_if_fail (gtk_tree_selection_path_is_selected (selection, path) == FALSE); + + /* Nothing should be selected at this point. */ + g_return_if_fail (gtk_tree_selection_count_selected_rows (selection) == 0); + + /* Check that selection really still works. */ + gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path, NULL, FALSE); + g_return_if_fail (gtk_tree_selection_path_is_selected (selection, path) == TRUE); + g_return_if_fail (gtk_tree_selection_count_selected_rows (selection) == 1); + + /* Expand and select child node now. */ + gtk_tree_path_append_index (path, 1); + gtk_tree_view_expand_all (GTK_TREE_VIEW (view)); + + gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path, NULL, FALSE); + g_return_if_fail (gtk_tree_selection_path_is_selected (selection, path) == TRUE); + g_return_if_fail (gtk_tree_selection_count_selected_rows (selection) == 1); + + gtk_tree_path_free (path); +} + +int +main (int argc, + char **argv) +{ + gtk_test_init (&argc, &argv, NULL); + + g_test_add_func ("/TreeView/cursor/bug-546005", test_bug_546005); + g_test_add_func ("/TreeView/cursor/bug-539377", test_bug_539377); + g_test_add_func ("/TreeView/cursor/select-collapsed_row", + test_select_collapsed_row); + + return g_test_run (); +} diff --git a/gtk/updateiconcache.c b/gtk/updateiconcache.c index 627f49eb80..3b927011cc 100644 --- a/gtk/updateiconcache.c +++ b/gtk/updateiconcache.c @@ -1516,9 +1516,11 @@ opentmp: g_unlink (bak_cache_path); if (g_rename (cache_path, bak_cache_path) == -1) { + int errsv = errno; + g_printerr (_("Could not rename %s to %s: %s, removing %s then.\n"), cache_path, bak_cache_path, - g_strerror (errno), + g_strerror (errsv), cache_path); g_unlink (cache_path); bak_cache_path = NULL; @@ -1528,16 +1530,22 @@ opentmp: if (g_rename (tmp_cache_path, cache_path) == -1) { + int errsv = errno; + g_printerr (_("Could not rename %s to %s: %s\n"), tmp_cache_path, cache_path, - g_strerror (errno)); + g_strerror (errsv)); g_unlink (tmp_cache_path); #ifdef G_OS_WIN32 if (bak_cache_path != NULL) if (g_rename (bak_cache_path, cache_path) == -1) - g_printerr (_("Could not rename %s back to %s: %s.\n"), - bak_cache_path, cache_path, - g_strerror (errno)); + { + errsv = errno; + + g_printerr (_("Could not rename %s back to %s: %s.\n"), + bak_cache_path, cache_path, + g_strerror (errsv)); + } #endif exit (1); } @@ -1648,8 +1656,12 @@ main (int argc, char **argv) setlocale (LC_ALL, ""); +#ifdef ENABLE_NLS bindtextdomain (GETTEXT_PACKAGE, GTK_LOCALEDIR); +#ifdef HAVE_BIND_TEXTDOMAIN_CODESET bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); +#endif +#endif context = g_option_context_new ("ICONPATH"); g_option_context_add_main_entries (context, args, GETTEXT_PACKAGE); diff --git a/modules/engines/ms-windows/msw_style.c b/modules/engines/ms-windows/msw_style.c index bc253e103a..a21494b298 100755 --- a/modules/engines/ms-windows/msw_style.c +++ b/modules/engines/ms-windows/msw_style.c @@ -550,8 +550,8 @@ get_windows_version () if (!have_version) { - have_version = TRUE; OSVERSIONINFOEX osvi; + have_version = TRUE; ZeroMemory (&osvi, sizeof (OSVERSIONINFOEX)); osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX); diff --git a/modules/other/gail/gailbutton.c b/modules/other/gail/gailbutton.c index b8ab7cd77d..998ec29a2f 100644 --- a/modules/other/gail/gailbutton.c +++ b/modules/other/gail/gailbutton.c @@ -154,10 +154,8 @@ gail_button_class_init (GailButtonClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); AtkObjectClass *class = ATK_OBJECT_CLASS (klass); - GailWidgetClass *widget_class; GailContainerClass *container_class; - widget_class = (GailWidgetClass*)klass; container_class = (GailContainerClass*)klass; gobject_class->finalize = gail_button_finalize; @@ -876,7 +874,6 @@ gail_button_ref_state_set (AtkObject *obj) { AtkStateSet *state_set; GtkWidget *widget; - GtkButton *button; state_set = ATK_OBJECT_CLASS (gail_button_parent_class)->ref_state_set (obj); widget = GTK_ACCESSIBLE (obj)->widget; @@ -884,8 +881,6 @@ gail_button_ref_state_set (AtkObject *obj) if (widget == NULL) return state_set; - button = GTK_BUTTON (widget); - if (GTK_WIDGET_STATE (widget) == GTK_STATE_ACTIVE) atk_state_set_add_state (state_set, ATK_STATE_ARMED); diff --git a/modules/other/gail/gailcombobox.c b/modules/other/gail/gailcombobox.c index b90e7cc199..e246aa32eb 100644 --- a/modules/other/gail/gailcombobox.c +++ b/modules/other/gail/gailcombobox.c @@ -358,15 +358,14 @@ gail_combo_box_get_keybinding (AtkAction *action, { GailComboBox *combo_box; gchar *return_value = NULL; - combo_box = GAIL_COMBO_BOX (action); switch (i) { case 0: { - GtkWidget *widget; + GtkWidget *widget; GtkWidget *label; AtkRelationSet *set; - AtkRelation *relation; + AtkRelation *relation; GPtrArray *target; gpointer target_object; guint key_val; @@ -375,7 +374,7 @@ gail_combo_box_get_keybinding (AtkAction *action, widget = GTK_ACCESSIBLE (combo_box)->widget; if (widget == NULL) return NULL; - set = atk_object_ref_relation_set (ATK_OBJECT (action)); + set = atk_object_ref_relation_set (ATK_OBJECT (action)); if (!set) return NULL; label = NULL; @@ -388,7 +387,7 @@ gail_combo_box_get_keybinding (AtkAction *action, { label = GTK_ACCESSIBLE (target_object)->widget; } - } + } g_object_unref (set); if (GTK_IS_LABEL (label)) { @@ -398,7 +397,8 @@ gail_combo_box_get_keybinding (AtkAction *action, } g_free (combo_box->press_keybinding); combo_box->press_keybinding = return_value; - break; } + break; + } default: break; } diff --git a/modules/other/gail/gailmenuitem.c b/modules/other/gail/gailmenuitem.c index 2accc8389d..24b1a853d5 100644 --- a/modules/other/gail/gailmenuitem.c +++ b/modules/other/gail/gailmenuitem.c @@ -33,6 +33,7 @@ static void gail_menu_item_real_initialize static gint gail_menu_item_get_n_children (AtkObject *obj); static AtkObject* gail_menu_item_ref_child (AtkObject *obj, gint i); +static AtkStateSet* gail_menu_item_ref_state_set (AtkObject *obj); static void gail_menu_item_finalize (GObject *object); static void atk_action_interface_init (AtkActionIface *iface); @@ -73,6 +74,7 @@ gail_menu_item_class_init (GailMenuItemClass *klass) class->get_n_children = gail_menu_item_get_n_children; class->ref_child = gail_menu_item_ref_child; + class->ref_state_set = gail_menu_item_ref_state_set; class->initialize = gail_menu_item_real_initialize; } @@ -239,6 +241,31 @@ gail_menu_item_ref_child (AtkObject *obj, return accessible; } +static AtkStateSet* +gail_menu_item_ref_state_set (AtkObject *obj) +{ + AtkObject *menu_item; + AtkStateSet *state_set, *parent_state_set; + + state_set = ATK_OBJECT_CLASS (gail_menu_item_parent_class)->ref_state_set (obj); + + menu_item = atk_object_get_parent (obj); + + if (menu_item) + { + if (!GTK_IS_MENU_ITEM (GTK_ACCESSIBLE (menu_item)->widget)) + return state_set; + + parent_state_set = atk_object_ref_state_set (menu_item); + if (!atk_state_set_contains_state (parent_state_set, ATK_STATE_SELECTED)) + { + atk_state_set_remove_state (state_set, ATK_STATE_FOCUSED); + atk_state_set_remove_state (state_set, ATK_STATE_SHOWING); + } + } + return state_set; +} + static void atk_action_interface_init (AtkActionIface *iface) { @@ -608,10 +635,18 @@ menu_item_selection (GtkItem *item, gboolean selected) { AtkObject *obj, *parent; + gint i; obj = gtk_widget_get_accessible (GTK_WIDGET (item)); atk_object_notify_state_change (obj, ATK_STATE_SELECTED, selected); - + + for (i = 0; i < atk_object_get_n_accessible_children (obj); i++) + { + AtkObject *child; + child = atk_object_ref_accessible_child (obj, i); + atk_object_notify_state_change (child, ATK_STATE_SHOWING, selected); + g_object_unref (child); + } parent = atk_object_get_parent (obj); g_signal_emit_by_name (parent, "selection_changed"); } diff --git a/modules/other/gail/gailscalebutton.c b/modules/other/gail/gailscalebutton.c index aa0ac2fb7b..32cb12eea9 100644 --- a/modules/other/gail/gailscalebutton.c +++ b/modules/other/gail/gailscalebutton.c @@ -187,12 +187,10 @@ static void gail_scale_button_get_current_value (AtkValue *obj, GValue *value) { - GailScaleButton *scale_button; GtkScaleButton *gtk_scale_button; g_return_if_fail (GAIL_IS_SCALE_BUTTON (obj)); - scale_button = GAIL_SCALE_BUTTON (obj); gtk_scale_button = GTK_SCALE_BUTTON (GTK_ACCESSIBLE (obj)->widget); g_value_set_double (g_value_init (value, G_TYPE_DOUBLE), diff --git a/modules/other/gail/gailwidget.c b/modules/other/gail/gailwidget.c index 3d0eed88b1..9493fc4eb2 100644 --- a/modules/other/gail/gailwidget.c +++ b/modules/other/gail/gailwidget.c @@ -106,6 +106,7 @@ static void gail_widget_real_initialize (AtkObject *obj, gpointer data); static GtkWidget* gail_widget_find_viewport (GtkWidget *widget); static gboolean gail_widget_on_screen (GtkWidget *widget); +static gboolean gail_widget_all_parents_visible(GtkWidget *widget); G_DEFINE_TYPE_WITH_CODE (GailWidget, gail_widget, GTK_TYPE_ACCESSIBLE, G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, atk_component_interface_init)) @@ -518,8 +519,8 @@ gail_widget_ref_state_set (AtkObject *accessible) if (GTK_WIDGET_VISIBLE (widget)) { atk_state_set_add_state (state_set, ATK_STATE_VISIBLE); - if (gail_widget_on_screen (widget) && - GTK_WIDGET_MAPPED (widget)) + if (gail_widget_on_screen (widget) && GTK_WIDGET_MAPPED (widget) && + gail_widget_all_parents_visible (widget)) { atk_state_set_add_state (state_set, ATK_STATE_SHOWING); } @@ -1079,3 +1080,30 @@ static gboolean gail_widget_on_screen (GtkWidget *widget) return return_value; } + +/** + * gail_widget_all_parents_visible: + * @widget: a #GtkWidget + * + * Checks if all the predecesors (the parent widget, his parent, etc) are visible + * Used to check properly the SHOWING state. + * + * Return value: TRUE if all the parent hierarchy is visible, FALSE otherwise + **/ +static gboolean gail_widget_all_parents_visible (GtkWidget *widget) +{ + GtkWidget *iter_parent = NULL; + gboolean result = TRUE; + + for (iter_parent = gtk_widget_get_parent (widget); iter_parent; + iter_parent = gtk_widget_get_parent (iter_parent)) + { + if (!GTK_WIDGET_VISIBLE (iter_parent)) + { + result = FALSE; + break; + } + } + + return result; +} diff --git a/modules/printbackends/cups/gtkcupsutils.c b/modules/printbackends/cups/gtkcupsutils.c index bcd03dc4be..cd97f10efd 100644 --- a/modules/printbackends/cups/gtkcupsutils.c +++ b/modules/printbackends/cups/gtkcupsutils.c @@ -187,6 +187,10 @@ gtk_cups_request_new_with_username (http_t *connection, "requesting-user-name", NULL, cupsUser ()); + request->auth_info_required = NULL; + request->auth_info = NULL; + request->need_auth_info = FALSE; + cupsLangFree (language); return request; @@ -241,6 +245,7 @@ gtk_cups_request_free (GtkCupsRequest *request) } g_free (request->username); + g_strfreev (request->auth_info_required); gtk_cups_result_free (request->result); diff --git a/modules/printbackends/cups/gtkcupsutils.h b/modules/printbackends/cups/gtkcupsutils.h index 47fd106e93..ba43f875f7 100644 --- a/modules/printbackends/cups/gtkcupsutils.h +++ b/modules/printbackends/cups/gtkcupsutils.h @@ -99,6 +99,9 @@ struct _GtkCupsRequest gint own_http : 1; gint need_password : 1; + gint need_auth_info : 1; + gchar **auth_info_required; + gchar **auth_info; GtkCupsPasswordState password_state; }; diff --git a/modules/printbackends/cups/gtkprintbackendcups.c b/modules/printbackends/cups/gtkprintbackendcups.c index 6491e347f0..7fd39847f1 100644 --- a/modules/printbackends/cups/gtkprintbackendcups.c +++ b/modules/printbackends/cups/gtkprintbackendcups.c @@ -94,6 +94,8 @@ typedef struct GtkCupsRequest *request; GPollFD *data_poll; GtkPrintBackendCups *backend; + GtkPrintCupsResponseCallbackFunc callback; + gpointer callback_data; } GtkPrintCupsDispatchWatch; @@ -110,13 +112,12 @@ struct _GtkPrintBackendCups guint list_printers_poll; guint list_printers_pending : 1; + gint list_printers_attempts; guint got_default_printer : 1; guint default_printer_poll; GtkCupsConnectionTest *cups_connection_test; char **covers; - char *default_cover_before; - char *default_cover_after; int number_of_covers; GList *requests; @@ -156,7 +157,7 @@ static GList * cups_printer_list_papers (GtkPrinter static GtkPageSetup * cups_printer_get_default_page_size (GtkPrinter *printer); static void cups_printer_request_details (GtkPrinter *printer); static gboolean cups_request_default_printer (GtkPrintBackendCups *print_backend); -static void cups_request_ppd (GtkPrinter *printer); +static gboolean cups_request_ppd (GtkPrinter *printer); static void cups_printer_get_hard_margins (GtkPrinter *printer, double *top, double *bottom, @@ -181,13 +182,13 @@ static cairo_surface_t * cups_printer_create_cairo_surface (GtkPrinter gdouble height, GIOChannel *cache_io); -static void gtk_print_backend_cups_set_password (GtkPrintBackend *backend, - const gchar *hostname, - const gchar *username, - const gchar *password); +static void gtk_print_backend_cups_set_password (GtkPrintBackend *backend, + gchar **auth_info_required, + gchar **auth_info); -void overwrite_and_free (gpointer data); -static gboolean is_address_local (const gchar *address); +void overwrite_and_free (gpointer data); +static gboolean is_address_local (const gchar *address); +static gboolean request_auth_info (gpointer data); static void gtk_print_backend_cups_register_type (GTypeModule *module) @@ -363,16 +364,14 @@ cups_printer_create_cairo_surface (GtkPrinter *printer, if (sscanf (ppd_attr_res->value, "%dx%ddpi", &res_x, &res_y) == 2) { - if (res_x != 0 && res_y != 0) + if (res_x > 0 && res_y > 0) gtk_print_settings_set_resolution_xy (settings, res_x, res_y); } else if (sscanf (ppd_attr_res->value, "%ddpi", &res) == 1) { - if (res != 0) + if (res > 0) gtk_print_settings_set_resolution (settings, res); } - else - gtk_print_settings_set_resolution (settings, 300); } } @@ -392,17 +391,10 @@ cups_printer_create_cairo_surface (GtkPrinter *printer, ppd_attr_screen_freq = ppdFindAttr (ppd_file, "ScreenFreq", NULL); - if (ppd_attr_res_screen_freq != NULL) + if (ppd_attr_res_screen_freq != NULL && atof (ppd_attr_res_screen_freq->value) > 0.0) gtk_print_settings_set_printer_lpi (settings, atof (ppd_attr_res_screen_freq->value)); - else if (ppd_attr_screen_freq != NULL) + else if (ppd_attr_screen_freq != NULL && atof (ppd_attr_screen_freq->value) > 0.0) gtk_print_settings_set_printer_lpi (settings, atof (ppd_attr_screen_freq->value)); - else - gtk_print_settings_set_printer_lpi (settings, 150.0); - } - else - { - gtk_print_settings_set_resolution (settings, 300); - gtk_print_settings_set_printer_lpi (settings, 150.0); } if (level == 2) @@ -568,6 +560,9 @@ gtk_print_backend_cups_print_stream (GtkPrintBackend *print_backend, ps->dnotify = dnotify; ps->job = g_object_ref (job); + request->need_auth_info = cups_printer->auth_info_required != NULL; + request->auth_info_required = g_strdupv (cups_printer->auth_info_required); + cups_request_execute (GTK_PRINT_BACKEND_CUPS (print_backend), request, (GtkPrintCupsResponseCallbackFunc) cups_print_cb, @@ -592,14 +587,13 @@ gtk_print_backend_cups_init (GtkPrintBackendCups *backend_cups) backend_cups->list_printers_poll = FALSE; backend_cups->got_default_printer = FALSE; backend_cups->list_printers_pending = FALSE; + backend_cups->list_printers_attempts = 0; backend_cups->requests = NULL; backend_cups->auth = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, overwrite_and_free); backend_cups->authentication_lock = FALSE; backend_cups->covers = NULL; - backend_cups->default_cover_before = NULL; - backend_cups->default_cover_after = NULL; backend_cups->number_of_covers = 0; backend_cups->default_printer_poll = 0; @@ -626,9 +620,6 @@ gtk_print_backend_cups_finalize (GObject *object) g_strfreev (backend_cups->covers); backend_cups->number_of_covers = 0; - g_free (backend_cups->default_cover_before); - g_free (backend_cups->default_cover_after); - gtk_cups_connection_test_free (backend_cups->cups_connection_test); backend_cups->cups_connection_test = NULL; @@ -652,6 +643,7 @@ gtk_print_backend_cups_dispose (GObject *object) if (backend_cups->list_printers_poll > 0) g_source_remove (backend_cups->list_printers_poll); backend_cups->list_printers_poll = 0; + backend_cups->list_printers_attempts = 0; if (backend_cups->default_printer_poll > 0) g_source_remove (backend_cups->default_printer_poll); @@ -672,18 +664,38 @@ is_address_local (const gchar *address) } static void -gtk_print_backend_cups_set_password (GtkPrintBackend *backend, - const gchar *hostname, - const gchar *username, - const gchar *password) +gtk_print_backend_cups_set_password (GtkPrintBackend *backend, + gchar **auth_info_required, + gchar **auth_info) { GtkPrintBackendCups *cups_backend = GTK_PRINT_BACKEND_CUPS (backend); GList *l; char dispatch_hostname[HTTP_MAX_URI]; gchar *key; + gchar *username = NULL; + gchar *hostname = NULL; + gchar *password = NULL; + gint length; + gint i; - key = g_strconcat (username, "@", hostname, NULL); - g_hash_table_insert (cups_backend->auth, key, g_strdup (password)); + length = g_strv_length (auth_info_required); + + if (auth_info != NULL) + for (i = 0; i < length; i++) + { + if (g_strcmp0 (auth_info_required[i], "username") == 0) + username = g_strdup (auth_info[i]); + else if (g_strcmp0 (auth_info_required[i], "hostname") == 0) + hostname = g_strdup (auth_info[i]); + else if (g_strcmp0 (auth_info_required[i], "password") == 0) + password = g_strdup (auth_info[i]); + } + + if (hostname != NULL && username != NULL && password != NULL) + { + key = g_strconcat (username, "@", hostname, NULL); + g_hash_table_insert (cups_backend->auth, key, g_strdup (password)); + } g_free (cups_backend->username); cups_backend->username = g_strdup (username); @@ -699,7 +711,18 @@ gtk_print_backend_cups_set_password (GtkPrintBackend *backend, if (is_address_local (dispatch_hostname)) strcpy (dispatch_hostname, "localhost"); - if (strcmp (hostname, dispatch_hostname) == 0) + if (dispatch->request->need_auth_info) + { + if (auth_info != NULL) + { + dispatch->request->auth_info = g_new0 (gchar *, length + 1); + for (i = 0; i < length; i++) + dispatch->request->auth_info[i] = g_strdup (auth_info[i]); + } + dispatch->backend->authentication_lock = FALSE; + dispatch->request->need_auth_info = FALSE; + } + else if (dispatch->request->password_state == GTK_CUPS_PASSWORD_REQUESTED || auth_info == NULL) { overwrite_and_free (dispatch->request->password); dispatch->request->password = g_strdup (password); @@ -720,6 +743,12 @@ request_password (gpointer data) gchar *prompt = NULL; gchar *key = NULL; char hostname[HTTP_MAX_URI]; + gchar **auth_info_required; + gchar **auth_info_default; + gchar **auth_info_display; + gboolean *auth_info_visible; + gint length = 3; + gint i; if (dispatch->backend->authentication_lock) return FALSE; @@ -733,6 +762,22 @@ request_password (gpointer data) else username = cupsUser (); + auth_info_required = g_new0 (gchar*, length + 1); + auth_info_required[0] = g_strdup ("hostname"); + auth_info_required[1] = g_strdup ("username"); + auth_info_required[2] = g_strdup ("password"); + + auth_info_default = g_new0 (gchar*, length + 1); + auth_info_default[0] = g_strdup (hostname); + auth_info_default[1] = g_strdup (username); + + auth_info_display = g_new0 (gchar*, length + 1); + auth_info_display[1] = g_strdup (_("Username:")); + auth_info_display[2] = g_strdup (_("Password:")); + + auth_info_visible = g_new0 (gboolean, length + 1); + auth_info_visible[1] = TRUE; + key = g_strconcat (username, "@", hostname, NULL); password = g_hash_table_lookup (dispatch->backend->auth, key); @@ -800,16 +845,199 @@ request_password (gpointer data) g_free (printer_name); g_signal_emit_by_name (dispatch->backend, "request-password", - hostname, username, prompt); + auth_info_required, auth_info_default, auth_info_display, auth_info_visible, prompt); g_free (prompt); } + for (i = 0; i < length; i++) + { + g_free (auth_info_required[i]); + g_free (auth_info_default[i]); + g_free (auth_info_display[i]); + } + + g_free (auth_info_required); + g_free (auth_info_default); + g_free (auth_info_display); + g_free (auth_info_visible); g_free (key); return FALSE; } +static void +cups_dispatch_add_poll (GSource *source) +{ + GtkPrintCupsDispatchWatch *dispatch; + GtkCupsPollState poll_state; + + dispatch = (GtkPrintCupsDispatchWatch *) source; + + poll_state = gtk_cups_request_get_poll_state (dispatch->request); + + if (dispatch->request->http != NULL) + { + if (dispatch->data_poll == NULL) + { + dispatch->data_poll = g_new0 (GPollFD, 1); + + if (poll_state == GTK_CUPS_HTTP_READ) + dispatch->data_poll->events = G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_PRI; + else if (poll_state == GTK_CUPS_HTTP_WRITE) + dispatch->data_poll->events = G_IO_OUT | G_IO_ERR; + else + dispatch->data_poll->events = 0; + +#ifdef HAVE_CUPS_API_1_2 + dispatch->data_poll->fd = httpGetFd (dispatch->request->http); +#else + dispatch->data_poll->fd = dispatch->request->http->fd; +#endif + g_source_add_poll (source, dispatch->data_poll); + } + } +} + +static gboolean +check_auth_info (gpointer user_data) +{ + GtkPrintCupsDispatchWatch *dispatch; + dispatch = (GtkPrintCupsDispatchWatch *) user_data; + + if (!dispatch->request->need_auth_info) + { + if (dispatch->request->auth_info == NULL) + { + dispatch->callback (GTK_PRINT_BACKEND (dispatch->backend), + gtk_cups_request_get_result (dispatch->request), + dispatch->callback_data); + g_source_destroy ((GSource *) dispatch); + } + else + { + gint length; + gint i; + + length = g_strv_length (dispatch->request->auth_info_required); + + gtk_cups_request_ipp_add_strings (dispatch->request, + IPP_TAG_JOB, + IPP_TAG_TEXT, + "auth-info", + length, + NULL, + dispatch->request->auth_info); + + g_source_attach ((GSource *) dispatch, NULL); + g_source_unref ((GSource *) dispatch); + + for (i = 0; i < length; i++) + overwrite_and_free (dispatch->request->auth_info[i]); + g_free (dispatch->request->auth_info); + dispatch->request->auth_info = NULL; + } + + return FALSE; + } + + return TRUE; +} + +static gboolean +request_auth_info (gpointer user_data) +{ + GtkPrintCupsDispatchWatch *dispatch; + const char *job_title; + const char *printer_uri; + gchar *prompt = NULL; + char *printer_name = NULL; + gint length; + gint i; + gboolean *auth_info_visible = NULL; + gchar **auth_info_default = NULL; + gchar **auth_info_display = NULL; + + dispatch = (GtkPrintCupsDispatchWatch *) user_data; + + if (dispatch->backend->authentication_lock) + return FALSE; + + job_title = gtk_cups_request_ipp_get_string (dispatch->request, IPP_TAG_NAME, "job-name"); + printer_uri = gtk_cups_request_ipp_get_string (dispatch->request, IPP_TAG_URI, "printer-uri"); + length = g_strv_length (dispatch->request->auth_info_required); + + auth_info_visible = g_new0 (gboolean, length); + auth_info_default = g_new0 (gchar *, length + 1); + auth_info_display = g_new0 (gchar *, length + 1); + + for (i = 0; i < length; i++) + { + if (g_strcmp0 (dispatch->request->auth_info_required[i], "domain") == 0) + { + auth_info_display[i] = g_strdup (_("Domain:")); + auth_info_default[i] = g_strdup ("WORKGROUP"); + auth_info_visible[i] = TRUE; + } + else if (g_strcmp0 (dispatch->request->auth_info_required[i], "username") == 0) + { + auth_info_display[i] = g_strdup (_("Username:")); + if (dispatch->backend->username != NULL) + auth_info_default[i] = g_strdup (dispatch->backend->username); + else + auth_info_default[i] = g_strdup (cupsUser ()); + auth_info_visible[i] = TRUE; + } + else if (g_strcmp0 (dispatch->request->auth_info_required[i], "password") == 0) + { + auth_info_display[i] = g_strdup (_("Password:")); + auth_info_visible[i] = FALSE; + } + } + + if (printer_uri != NULL && strrchr (printer_uri, '/') != NULL) + printer_name = g_strdup (strrchr (printer_uri, '/') + 1); + + dispatch->backend->authentication_lock = TRUE; + + if (job_title != NULL) + { + if (printer_name != NULL) + prompt = g_strdup_printf ( _("Authentication is required to print document '%s' on printer %s"), job_title, printer_name); + else + prompt = g_strdup_printf ( _("Authentication is required to print document '%s'"), job_title); + } + else + { + if (printer_name != NULL) + prompt = g_strdup_printf ( _("Authentication is required to print this document on printer %s"), printer_name); + else + prompt = g_strdup ( _("Authentication is required to print this document")); + } + + g_signal_emit_by_name (dispatch->backend, "request-password", + dispatch->request->auth_info_required, + auth_info_default, + auth_info_display, + auth_info_visible, + prompt); + + for (i = 0; i < length; i++) + { + g_free (auth_info_default[i]); + g_free (auth_info_display[i]); + } + + g_free (auth_info_default); + g_free (auth_info_display); + g_free (printer_name); + g_free (prompt); + + g_idle_add (check_auth_info, user_data); + + return FALSE; +} + static gboolean cups_dispatch_watch_check (GSource *source) { @@ -824,29 +1052,7 @@ cups_dispatch_watch_check (GSource *source) poll_state = gtk_cups_request_get_poll_state (dispatch->request); - if (dispatch->request->http != NULL) - { - if (dispatch->data_poll == NULL) - { - dispatch->data_poll = g_new0 (GPollFD, 1); - g_source_add_poll (source, dispatch->data_poll); - } - else - { - if (poll_state == GTK_CUPS_HTTP_READ) - dispatch->data_poll->events = G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_PRI; - else if (poll_state == GTK_CUPS_HTTP_WRITE) - dispatch->data_poll->events = G_IO_OUT | G_IO_ERR; - else - dispatch->data_poll->events = 0; - } - -#ifdef HAVE_CUPS_API_1_2 - dispatch->data_poll->fd = httpGetFd (dispatch->request->http); -#else - dispatch->data_poll->fd = dispatch->request->http->fd; -#endif - } + cups_dispatch_add_poll (source); if (poll_state != GTK_CUPS_HTTP_IDLE && !dispatch->request->need_password) if (!(dispatch->data_poll->revents & dispatch->data_poll->events)) @@ -875,6 +1081,7 @@ cups_dispatch_watch_prepare (GSource *source, gint *timeout_) { GtkPrintCupsDispatchWatch *dispatch; + gboolean result; dispatch = (GtkPrintCupsDispatchWatch *) source; @@ -883,7 +1090,11 @@ cups_dispatch_watch_prepare (GSource *source, *timeout_ = -1; - return gtk_cups_request_read_write (dispatch->request); + result = gtk_cups_request_read_write (dispatch->request); + + cups_dispatch_add_poll (source); + + return result; } static gboolean @@ -1008,13 +1219,24 @@ cups_request_execute (GtkPrintBackendCups *print_backend, dispatch->request = request; dispatch->backend = g_object_ref (print_backend); dispatch->data_poll = NULL; + dispatch->callback = NULL; + dispatch->callback_data = NULL; print_backend->requests = g_list_prepend (print_backend->requests, dispatch); g_source_set_callback ((GSource *) dispatch, (GSourceFunc) callback, user_data, notify); - g_source_attach ((GSource *) dispatch, NULL); - g_source_unref ((GSource *) dispatch); + if (request->need_auth_info) + { + dispatch->callback = callback; + dispatch->callback_data = user_data; + request_auth_info (dispatch); + } + else + { + g_source_attach ((GSource *) dispatch, NULL); + g_source_unref ((GSource *) dispatch); + } } #if 0 @@ -1333,6 +1555,7 @@ cups_request_printer_list_cb (GtkPrintBackendCups *cups_backend, ipp_t *response; gboolean list_has_changed; GList *removed_printer_checklist; + gchar *remote_default_printer = NULL; GDK_THREADS_ENTER (); @@ -1358,6 +1581,7 @@ cups_request_printer_list_cb (GtkPrintBackendCups *cups_backend, if (cups_backend->list_printers_poll > 0) g_source_remove (cups_backend->list_printers_poll); cups_backend->list_printers_poll = 0; + cups_backend->list_printers_attempts = 0; } goto done; @@ -1431,6 +1655,10 @@ cups_request_printer_list_cb (GtkPrintBackendCups *cups_backend, gboolean is_accepting_jobs = TRUE; gboolean default_printer = FALSE; gboolean got_printer_type = FALSE; + gchar *default_cover_before = NULL; + gchar *default_cover_after = NULL; + gboolean remote_printer = FALSE; + gchar **auth_info_required = NULL; /* Skip leading attributes until we hit a printer... */ @@ -1523,22 +1751,17 @@ cups_request_printer_list_cb (GtkPrintBackendCups *cups_backend, { cups_backend->number_of_covers = attr->num_values; cups_backend->covers = g_new (char *, cups_backend->number_of_covers + 1); - for (i = 0; i < cups_backend->number_of_covers; i++) cups_backend->covers[i] = g_strdup (attr->values[i].string.text); - cups_backend->covers[cups_backend->number_of_covers] = NULL; } } else if (strcmp (attr->name, "job-sheets-default") == 0) { - if ( (cups_backend->default_cover_before == NULL) && (cups_backend->default_cover_after == NULL)) + if (attr->num_values == 2) { - if (attr->num_values == 2) - { - cups_backend->default_cover_before = g_strdup (attr->values[0].string.text); - cups_backend->default_cover_after = g_strdup (attr->values[1].string.text); - } + default_cover_before = attr->values[0].string.text; + default_cover_after = attr->values[1].string.text; } } else if (strcmp (attr->name, "printer-type") == 0) @@ -1548,6 +1771,20 @@ cups_request_printer_list_cb (GtkPrintBackendCups *cups_backend, default_printer = TRUE; else default_printer = FALSE; + + if (attr->values[0].integer & 0x00000002) + remote_printer = TRUE; + else + remote_printer = FALSE; + } + else if (strcmp (attr->name, "auth-info-required") == 0) + { + if (strcmp (attr->values[0].string.text, "none") != 0) + { + auth_info_required = g_new0 (gchar *, attr->num_values + 1); + for (i = 0; i < attr->num_values; i++) + auth_info_required[i] = g_strdup (attr->values[i].string.text); + } } else { @@ -1571,8 +1808,16 @@ cups_request_printer_list_cb (GtkPrintBackendCups *cups_backend, { if (default_printer && !cups_backend->got_default_printer) { - cups_backend->got_default_printer = TRUE; - cups_backend->default_printer = g_strdup (printer_name); + if (!remote_printer) + { + cups_backend->got_default_printer = TRUE; + cups_backend->default_printer = g_strdup (printer_name); + } + else + { + if (remote_default_printer == NULL) + remote_default_printer = g_strdup (printer_name); + } } } else @@ -1656,9 +1901,15 @@ cups_request_printer_list_cb (GtkPrintBackendCups *cups_backend, g_free (cups_server); + cups_printer->default_cover_before = g_strdup (default_cover_before); + cups_printer->default_cover_after = g_strdup (default_cover_after); + cups_printer->hostname = g_strdup (hostname); cups_printer->port = port; + cups_printer->auth_info_required = g_strdupv (auth_info_required); + g_strfreev (auth_info_required); + printer = GTK_PRINTER (cups_printer); if (cups_backend->default_printer != NULL && @@ -1671,6 +1922,8 @@ cups_request_printer_list_cb (GtkPrintBackendCups *cups_backend, else g_object_ref (printer); + GTK_PRINTER_CUPS (printer)->remote = remote_printer; + gtk_printer_set_is_paused (printer, is_paused); gtk_printer_set_is_accepting_jobs (printer, is_accepting_jobs); @@ -1793,6 +2046,26 @@ done: gtk_print_backend_set_list_done (backend); + if (!cups_backend->got_default_printer && remote_default_printer != NULL) + { + cups_backend->default_printer = g_strdup (remote_default_printer); + cups_backend->got_default_printer = TRUE; + g_free (remote_default_printer); + + if (cups_backend->default_printer != NULL) + { + GtkPrinter *default_printer = NULL; + default_printer = gtk_print_backend_find_printer (GTK_PRINT_BACKEND (cups_backend), + cups_backend->default_printer); + if (default_printer != NULL) + { + gtk_printer_set_is_default (default_printer, TRUE); + g_signal_emit_by_name (GTK_PRINT_BACKEND (cups_backend), + "printer-status-changed", default_printer); + } + } + } + GDK_THREADS_LEAVE (); } @@ -1831,7 +2104,8 @@ cups_request_printer_list (GtkPrintBackendCups *cups_backend) "printer-is-accepting-jobs", "job-sheets-supported", "job-sheets-default", - "printer-type" + "printer-type", + "auth-info-required" }; if (cups_backend->list_printers_pending) @@ -1840,8 +2114,23 @@ cups_request_printer_list (GtkPrintBackendCups *cups_backend) state = gtk_cups_connection_test_get_state (cups_backend->cups_connection_test); update_backend_status (cups_backend, state); + if (cups_backend->list_printers_attempts == 60) + { + cups_backend->list_printers_attempts = -1; + if (cups_backend->list_printers_poll > 0) + g_source_remove (cups_backend->list_printers_poll); + cups_backend->list_printers_poll = gdk_threads_add_timeout (200, + (GSourceFunc) cups_request_printer_list, + cups_backend); + } + else if (cups_backend->list_printers_attempts != -1) + cups_backend->list_printers_attempts++; + if (state == GTK_CUPS_CONNECTION_IN_PROGRESS || state == GTK_CUPS_CONNECTION_NOT_AVAILABLE) return TRUE; + else + if (cups_backend->list_printers_attempts > 0) + cups_backend->list_printers_attempts = 60; cups_backend->list_printers_pending = TRUE; @@ -1879,9 +2168,9 @@ cups_get_printer_list (GtkPrintBackend *backend) if (cups_backend->list_printers_poll == 0) { if (cups_request_printer_list (cups_backend)) - cups_backend->list_printers_poll = gdk_threads_add_timeout_seconds (3, - (GSourceFunc) cups_request_printer_list, - backend); + cups_backend->list_printers_poll = gdk_threads_add_timeout (50, + (GSourceFunc) cups_request_printer_list, + backend); } } @@ -1950,7 +2239,7 @@ done: GDK_THREADS_LEAVE (); } -static void +static gboolean cups_request_ppd (GtkPrinter *printer) { GError *error; @@ -1970,6 +2259,41 @@ cups_request_ppd (GtkPrinter *printer) GTK_NOTE (PRINTING, g_print ("CUPS Backend: %s\n", G_STRFUNC)); + if (cups_printer->remote) + { + GtkCupsConnectionState state; + + state = gtk_cups_connection_test_get_state (cups_printer->remote_cups_connection_test); + + if (state == GTK_CUPS_CONNECTION_IN_PROGRESS) + { + if (cups_printer->get_remote_ppd_attempts == 60) + { + cups_printer->get_remote_ppd_attempts = -1; + if (cups_printer->get_remote_ppd_poll > 0) + g_source_remove (cups_printer->get_remote_ppd_poll); + cups_printer->get_remote_ppd_poll = gdk_threads_add_timeout (200, + (GSourceFunc) cups_request_ppd, + printer); + } + else if (cups_printer->get_remote_ppd_attempts != -1) + cups_printer->get_remote_ppd_attempts++; + + return TRUE; + } + + gtk_cups_connection_test_free (cups_printer->remote_cups_connection_test); + cups_printer->remote_cups_connection_test = NULL; + cups_printer->get_remote_ppd_poll = 0; + cups_printer->get_remote_ppd_attempts = 0; + + if (state == GTK_CUPS_CONNECTION_NOT_AVAILABLE) + { + g_signal_emit_by_name (printer, "details-acquired", FALSE); + return FALSE; + } + } + http = httpConnectEncrypt (cups_printer->hostname, cups_printer->port, cupsEncryption ()); @@ -1999,7 +2323,7 @@ cups_request_ppd (GtkPrinter *printer) g_free (data); g_signal_emit_by_name (printer, "details-acquired", FALSE); - return; + return FALSE; } data->http = http; @@ -2037,6 +2361,8 @@ cups_request_ppd (GtkPrinter *printer) g_free (resource); g_free (ppd_filename); + + return FALSE; } /* Ordering matters for default preference */ @@ -2209,9 +2535,9 @@ cups_get_default_printer (GtkPrintBackendCups *backend) if (cups_backend->default_printer_poll == 0) { if (cups_request_default_printer (cups_backend)) - cups_backend->default_printer_poll = gdk_threads_add_timeout (500, - (GSourceFunc) cups_request_default_printer, - backend); + cups_backend->default_printer_poll = gdk_threads_add_timeout (200, + (GSourceFunc) cups_request_default_printer, + backend); } } @@ -2334,7 +2660,22 @@ cups_printer_request_details (GtkPrinter *printer) cups_printer = GTK_PRINTER_CUPS (printer); if (!cups_printer->reading_ppd && gtk_printer_cups_get_ppd (cups_printer) == NULL) - cups_request_ppd (printer); + { + if (cups_printer->remote) + { + if (cups_printer->get_remote_ppd_poll == 0) + { + cups_printer->remote_cups_connection_test = gtk_cups_connection_test_new (cups_printer->hostname); + + if (cups_request_ppd (printer)) + cups_printer->get_remote_ppd_poll = gdk_threads_add_timeout (50, + (GSourceFunc) cups_request_ppd, + printer); + } + } + else + cups_request_ppd (printer); + } } static char * @@ -3136,6 +3477,7 @@ cups_printer_get_options (GtkPrinter *printer, cups_option_t *opts = NULL; GtkPrintBackendCups *backend; GtkTextDirection text_direction; + GtkPrinterCups *cups_printer = NULL; set = gtk_printer_option_set_new (); @@ -3200,8 +3542,9 @@ cups_printer_get_options (GtkPrinter *printer, g_object_unref (option); backend = GTK_PRINT_BACKEND_CUPS (gtk_printer_get_backend (printer)); + cups_printer = GTK_PRINTER_CUPS (printer); - if (backend != NULL) + if (backend != NULL && printer != NULL) { char *cover_default[] = {"none", "classified", "confidential", "secret", "standard", "topsecret", "unclassified" }; /* Translators, these strings are names for various 'standard' cover @@ -3246,8 +3589,8 @@ cups_printer_get_options (GtkPrinter *printer, gtk_printer_option_choices_from_array (option, num_of_covers, cover, cover_display_translated); - if (backend->default_cover_before != NULL) - gtk_printer_option_set (option, backend->default_cover_before); + if (cups_printer->default_cover_before != NULL) + gtk_printer_option_set (option, cups_printer->default_cover_before); else gtk_printer_option_set (option, "none"); set_option_from_settings (option, settings); @@ -3260,8 +3603,8 @@ cups_printer_get_options (GtkPrinter *printer, option = gtk_printer_option_new ("gtk-cover-after", _("After"), GTK_PRINTER_OPTION_TYPE_PICKONE); gtk_printer_option_choices_from_array (option, num_of_covers, cover, cover_display_translated); - if (backend->default_cover_after != NULL) - gtk_printer_option_set (option, backend->default_cover_after); + if (cups_printer->default_cover_after != NULL) + gtk_printer_option_set (option, cups_printer->default_cover_after); else gtk_printer_option_set (option, "none"); set_option_from_settings (option, settings); @@ -3735,12 +4078,12 @@ foreach_option_get_settings (GtkPrinterOption *option, if (sscanf (value, "%dx%ddpi", &res_x, &res_y) == 2) { - if (res_x != 0 && res_y != 0) + if (res_x > 0 && res_y > 0) gtk_print_settings_set_resolution_xy (settings, res_x, res_y); } else if (sscanf (value, "%ddpi", &res) == 1) { - if (res != 0) + if (res > 0) gtk_print_settings_set_resolution (settings, res); } diff --git a/modules/printbackends/cups/gtkprintercups.c b/modules/printbackends/cups/gtkprintercups.c index e54361957b..ddf4d1d8a5 100644 --- a/modules/printbackends/cups/gtkprintercups.c +++ b/modules/printbackends/cups/gtkprintercups.c @@ -75,6 +75,13 @@ gtk_printer_cups_init (GtkPrinterCups *printer) printer->port = 0; printer->ppd_name = NULL; printer->ppd_file = NULL; + printer->default_cover_before = NULL; + printer->default_cover_after = NULL; + printer->remote = FALSE; + printer->get_remote_ppd_poll = 0; + printer->get_remote_ppd_attempts = 0; + printer->remote_cups_connection_test = NULL; + printer->auth_info_required = NULL; } static void @@ -90,10 +97,19 @@ gtk_printer_cups_finalize (GObject *object) g_free (printer->printer_uri); g_free (printer->hostname); g_free (printer->ppd_name); + g_free (printer->default_cover_before); + g_free (printer->default_cover_after); + g_strfreev (printer->auth_info_required); if (printer->ppd_file) ppdClose (printer->ppd_file); + if (printer->get_remote_ppd_poll > 0) + g_source_remove (printer->get_remote_ppd_poll); + printer->get_remote_ppd_attempts = 0; + + gtk_cups_connection_test_free (printer->remote_cups_connection_test); + G_OBJECT_CLASS (gtk_printer_cups_parent_class)->finalize (object); } diff --git a/modules/printbackends/cups/gtkprintercups.h b/modules/printbackends/cups/gtkprintercups.h index 6f1c00d452..6868232f29 100644 --- a/modules/printbackends/cups/gtkprintercups.h +++ b/modules/printbackends/cups/gtkprintercups.h @@ -23,6 +23,7 @@ #include #include #include +#include "gtkcupsutils.h" #include @@ -47,11 +48,20 @@ struct _GtkPrinterCups gchar *printer_uri; gchar *hostname; gint port; + gchar **auth_info_required; ipp_pstate_t state; gboolean reading_ppd; gchar *ppd_name; ppd_file_t *ppd_file; + + gchar *default_cover_before; + gchar *default_cover_after; + + gboolean remote; + guint get_remote_ppd_poll; + gint get_remote_ppd_attempts; + GtkCupsConnectionTest *remote_cups_connection_test; }; struct _GtkPrinterCupsClass diff --git a/modules/printbackends/file/gtkprintbackendfile.c b/modules/printbackends/file/gtkprintbackendfile.c index 7bdaaa7b99..fc2046c595 100644 --- a/modules/printbackends/file/gtkprintbackendfile.c +++ b/modules/printbackends/file/gtkprintbackendfile.c @@ -32,6 +32,7 @@ #include #include #include +#include #include @@ -64,13 +65,15 @@ typedef enum { FORMAT_PDF, FORMAT_PS, + FORMAT_SVG, N_FORMATS } OutputFormat; static const gchar* formats[N_FORMATS] = { "pdf", - "ps" + "ps", + "svg" }; static GObjectClass *backend_parent_class; @@ -228,7 +231,19 @@ output_file_from_settings (GtkPrintSettings *settings, OutputFormat format; format = format_from_settings (settings); - extension = format == FORMAT_PS ? "ps" : "pdf"; + switch (format) + { + default: + case FORMAT_PDF: + extension = "pdf"; + break; + case FORMAT_PS: + extension = "ps"; + break; + case FORMAT_SVG: + extension = "svg"; + break; + } } /* default filename used for print-to-file */ @@ -298,16 +313,27 @@ file_printer_create_cairo_surface (GtkPrinter *printer, { cairo_surface_t *surface; OutputFormat format; + const cairo_svg_version_t *versions; + int num_versions = 0; format = format_from_settings (settings); - if (format == FORMAT_PS) - surface = cairo_ps_surface_create_for_stream (_cairo_write, cache_io, width, height); - else - surface = cairo_pdf_surface_create_for_stream (_cairo_write, cache_io, width, height); - - if (gtk_print_settings_get_printer_lpi (settings) == 0.0) - gtk_print_settings_set_printer_lpi (settings, 150.0); + switch (format) + { + default: + case FORMAT_PDF: + surface = cairo_pdf_surface_create_for_stream (_cairo_write, cache_io, width, height); + break; + case FORMAT_PS: + surface = cairo_ps_surface_create_for_stream (_cairo_write, cache_io, width, height); + break; + case FORMAT_SVG: + surface = cairo_svg_surface_create_for_stream (_cairo_write, cache_io, width, height); + cairo_svg_get_versions (&versions, &num_versions); + if (num_versions > 0) + cairo_svg_surface_restrict_to_version (surface, versions[num_versions - 1]); + break; + } cairo_surface_set_fallback_resolution (surface, 2.0 * gtk_print_settings_get_printer_lpi (settings), @@ -416,13 +442,11 @@ gtk_print_backend_file_print_stream (GtkPrintBackend *print_backend, GDestroyNotify dnotify) { GError *internal_error = NULL; - GtkPrinter *printer; _PrintStreamData *ps; GtkPrintSettings *settings; gchar *uri; GFile *file = NULL; - printer = gtk_print_job_get_printer (job); settings = gtk_print_job_get_settings (job); ps = g_new0 (_PrintStreamData, 1); @@ -472,7 +496,7 @@ gtk_print_backend_file_init (GtkPrintBackendFile *backend) NULL); gtk_printer_set_has_details (printer, TRUE); - gtk_printer_set_icon_name (printer, "gtk-floppy"); + gtk_printer_set_icon_name (printer, "gtk-save"); gtk_printer_set_is_active (printer, TRUE); gtk_print_backend_add_printer (GTK_PRINT_BACKEND (backend), printer); @@ -543,7 +567,7 @@ file_printer_get_options (GtkPrinter *printer, GtkPrinterOption *option; const gchar *n_up[] = {"1", "2", "4", "6", "9", "16" }; const gchar *pages_per_sheet = NULL; - const gchar *format_names[N_FORMATS] = { N_("PDF"), N_("Postscript") }; + const gchar *format_names[N_FORMATS] = { N_("PDF"), N_("Postscript"), N_("SVG") }; const gchar *supported_formats[N_FORMATS]; gchar *display_format_names[N_FORMATS]; gint n_formats = 0; @@ -591,7 +615,20 @@ file_printer_get_options (GtkPrinter *printer, } else { - current_format = format == FORMAT_PS ? FORMAT_PS : FORMAT_PDF; + switch (format) + { + default: + case FORMAT_PDF: + current_format = FORMAT_PDF; + break; + case FORMAT_PS: + current_format = FORMAT_PS; + break; + case FORMAT_SVG: + current_format = FORMAT_SVG; + break; + } + for (n_formats = 0; n_formats < N_FORMATS; ++n_formats) { supported_formats[n_formats] = formats[n_formats]; @@ -603,6 +640,7 @@ file_printer_get_options (GtkPrinter *printer, option = gtk_printer_option_new ("gtk-main-page-custom-input", _("File"), GTK_PRINTER_OPTION_TYPE_FILESAVE); + gtk_printer_option_set_activates_default (option, TRUE); gtk_printer_option_set (option, uri); g_free (uri); option->group = g_strdup ("GtkPrintDialogExtension"); diff --git a/modules/printbackends/lpr/gtkprintbackendlpr.c b/modules/printbackends/lpr/gtkprintbackendlpr.c index 9d9c932a0d..72d9c33e06 100644 --- a/modules/printbackends/lpr/gtkprintbackendlpr.c +++ b/modules/printbackends/lpr/gtkprintbackendlpr.c @@ -211,9 +211,6 @@ lpr_printer_create_cairo_surface (GtkPrinter *printer, surface = cairo_ps_surface_create_for_stream (_cairo_write, cache_io, width, height); - if (gtk_print_settings_get_printer_lpi (settings) == 0.0) - gtk_print_settings_set_printer_lpi (settings, 150.0); - cairo_surface_set_fallback_resolution (surface, 2.0 * gtk_print_settings_get_printer_lpi (settings), 2.0 * gtk_print_settings_get_printer_lpi (settings)); @@ -281,7 +278,7 @@ lpr_write (GIOChannel *source, { gsize bytes_written; - g_io_channel_write_chars (ps->in, + g_io_channel_write_chars (ps->in, buf, bytes_read, &bytes_written, @@ -323,21 +320,19 @@ gtk_print_backend_lpr_print_stream (GtkPrintBackend *print_backend, GDestroyNotify dnotify) { GError *print_error = NULL; - GtkPrinter *printer; _PrintStreamData *ps; GtkPrintSettings *settings; - gint argc; + gint argc; gint in_fd; gchar **argv = NULL; const char *cmd_line; - - printer = gtk_print_job_get_printer (job); + settings = gtk_print_job_get_settings (job); cmd_line = gtk_print_settings_get (settings, "lpr-commandline"); if (cmd_line == NULL) cmd_line = LPR_COMMAND; - + ps = g_new0 (_PrintStreamData, 1); ps->callback = callback; ps->user_data = user_data; @@ -347,7 +342,7 @@ gtk_print_backend_lpr_print_stream (GtkPrintBackend *print_backend, /* spawn lpr with pipes and pipe ps file to lpr */ if (!g_shell_parse_argv (cmd_line, &argc, &argv, &print_error)) - goto out; + goto out; if (!g_spawn_async_with_pipes (NULL, argv, @@ -369,13 +364,13 @@ gtk_print_backend_lpr_print_stream (GtkPrintBackend *print_backend, { if (ps->in != NULL) g_io_channel_unref (ps->in); - + goto out; } g_io_channel_set_close_on_unref (ps->in, TRUE); - g_io_add_watch (data_io, + g_io_add_watch (data_io, G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP, (GIOFunc) lpr_write, ps); @@ -431,6 +426,7 @@ lpr_printer_get_options (GtkPrinter *printer, g_object_unref (option); option = gtk_printer_option_new ("gtk-main-page-custom-input", _("Command Line"), GTK_PRINTER_OPTION_TYPE_STRING); + gtk_printer_option_set_activates_default (option, TRUE); option->group = g_strdup ("GtkPrintDialogExtension"); if (settings != NULL && (command = gtk_print_settings_get (settings, "lpr-commandline"))!= NULL) diff --git a/modules/printbackends/papi/gtkprintbackendpapi.c b/modules/printbackends/papi/gtkprintbackendpapi.c index eb16e1553d..7dba533eaa 100644 --- a/modules/printbackends/papi/gtkprintbackendpapi.c +++ b/modules/printbackends/papi/gtkprintbackendpapi.c @@ -234,8 +234,9 @@ papi_printer_create_cairo_surface (GtkPrinter *printer, surface = cairo_ps_surface_create_for_stream (_cairo_write, cache_io, width, height); - /* TODO: DPI from settings object? */ - cairo_surface_set_fallback_resolution (surface, 300, 300); + cairo_surface_set_fallback_resolution (surface, + 2.0 * gtk_print_settings_get_printer_lpi (settings), + 2.0 * gtk_print_settings_get_printer_lpi (settings)); return surface; } diff --git a/modules/printbackends/test/gtkprintbackendtest.c b/modules/printbackends/test/gtkprintbackendtest.c index 47037cbde3..c4a4e23f73 100644 --- a/modules/printbackends/test/gtkprintbackendtest.c +++ b/modules/printbackends/test/gtkprintbackendtest.c @@ -305,9 +305,6 @@ test_printer_create_cairo_surface (GtkPrinter *printer, else surface = cairo_pdf_surface_create_for_stream (_cairo_write, cache_io, width, height); - if (gtk_print_settings_get_printer_lpi (settings) == 0.0) - gtk_print_settings_set_printer_lpi (settings, 150.0); - cairo_surface_set_fallback_resolution (surface, 2.0 * gtk_print_settings_get_printer_lpi (settings), 2.0 * gtk_print_settings_get_printer_lpi (settings)); diff --git a/po-properties/Makefile.in.in b/po-properties/Makefile.in.in index efc1475059..db1b638778 100644 --- a/po-properties/Makefile.in.in +++ b/po-properties/Makefile.in.in @@ -33,10 +33,11 @@ localedir = $(libdir)/locale gnulocaledir = $(datadir)/locale gettextsrcdir = $(datadir)/glib-2.0/gettext/po subdir = po-properties +install_sh = @install_sh@ +mkdir_p = $(install_sh) -d INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ -MKINSTALLDIRS = $(top_srcdir)/@MKINSTALLDIRS@ CC = @CC@ GENCAT = @GENCAT@ @@ -105,12 +106,8 @@ install-exec: install-data: install-data-@USE_NLS@ install-data-no: all install-data-yes: all - if test -r "$(MKINSTALLDIRS)"; then \ - $(MKINSTALLDIRS) $(DESTDIR)$(datadir); \ - else \ - $(SHELL) $(top_srcdir)/mkinstalldirs $(DESTDIR)$(datadir); \ - fi - @catalogs='$(CATALOGS)'; \ + $(mkdir_p) $(DESTDIR)$(datadir); \ + catalogs='$(CATALOGS)'; \ for cat in $$catalogs; do \ cat=`basename $$cat`; \ case "$$cat" in \ @@ -119,11 +116,7 @@ install-data-yes: all esac; \ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \ dir=$(DESTDIR)$$destdir/$$lang/LC_MESSAGES; \ - if test -r "$(MKINSTALLDIRS)"; then \ - $(MKINSTALLDIRS) $$dir; \ - else \ - $(SHELL) $(top_srcdir)/mkinstalldirs $$dir; \ - fi; \ + $(mkdir_p) $$dir; \ if test -r $$cat; then \ $(INSTALL_DATA) $$cat $$dir/$(GETTEXT_PACKAGE)$(INSTOBJEXT); \ echo "installing $$cat as $$dir/$(GETTEXT_PACKAGE)$(INSTOBJEXT)"; \ @@ -147,11 +140,7 @@ install-data-yes: all fi; \ done if test "$(PACKAGE)" = "glib"; then \ - if test -r "$(MKINSTALLDIRS)"; then \ - $(MKINSTALLDIRS) $(DESTDIR)$(gettextsrcdir); \ - else \ - $(SHELL) $(top_srcdir)/mkinstalldirs $(DESTDIR)$(gettextsrcdir); \ - fi; \ + $(mkdir_p) $(DESTDIR)$(gettextsrcdir); \ $(INSTALL_DATA) $(srcdir)/Makefile.in.in \ $(DESTDIR)$(gettextsrcdir)/Makefile.in.in; \ else \ diff --git a/po-properties/POTFILES.in b/po-properties/POTFILES.in index 5bc1ea38fa..cacb30cda7 100644 --- a/po-properties/POTFILES.in +++ b/po-properties/POTFILES.in @@ -4,6 +4,7 @@ gdk-pixbuf/gdk-pixbuf-animation.c gdk-pixbuf/gdk-pixbuf-data.c gdk-pixbuf/gdk-pixbuf-io.c gdk-pixbuf/gdk-pixbuf-loader.c +gdk-pixbuf/gdk-pixbuf-simple-anim.c gdk-pixbuf/gdk-pixbuf.c gdk-pixbuf/gdk-pixdata.c gdk-pixbuf/io-ani.c @@ -27,6 +28,7 @@ gdk/gdk.c gdk/gdkdisplaymanager.c gdk/gdkpango.c gdk/gdkscreen.c +gdk/gdkwindow.c gdk/keyname-table.h gdk/win32/gdkmain-win32.c gdk/x11/gdkapplaunchcontext-x11.c @@ -38,6 +40,7 @@ gtk/gtkaccelmap.c gtk/gtkaccessible.c gtk/gtkaction.c gtk/gtkactiongroup.c +gtk/gtkactivatable.c gtk/gtkadjustment.c gtk/gtkalignment.c gtk/gtkarrow.c @@ -76,12 +79,14 @@ gtk/gtkcomboboxentry.c gtk/gtkcontainer.c gtk/gtkctree.c gtk/gtkcurve.c +gtk/gtkcustompaperunixdialog.c gtk/gtkdialog.c gtk/gtkdnd-quartz.c gtk/gtkdnd.c gtk/gtkdrawingarea.c gtk/gtkeditable.c gtk/gtkentry.c +gtk/gtkentrybuffer.c gtk/gtkentrycompletion.c gtk/gtkeventbox.c gtk/gtkexpander.c @@ -122,6 +127,7 @@ gtk/gtkimcontext.c gtk/gtkimcontextsimple.c gtk/gtkimmodule.c gtk/gtkimmulticontext.c +gtk/gtkinfobar.c gtk/gtkinputdialog.c gtk/gtkinvisible.c gtk/gtkitem.c @@ -142,6 +148,8 @@ gtk/gtkmessagedialog.c gtk/gtkmisc.c gtk/gtkmodules.c gtk/gtkmountoperation.c +gtk/gtkmountoperation-stub.c +gtk/gtkmountoperation-x11.c gtk/gtknotebook.c gtk/gtkobject.c gtk/gtkoldeditable.c @@ -262,5 +270,6 @@ modules/input/imxim.c modules/printbackends/cups/gtkprintbackendcups.c modules/printbackends/file/gtkprintbackendfile.c modules/printbackends/lpr/gtkprintbackendlpr.c +modules/printbackends/papi/gtkprintbackendpapi.c modules/printbackends/test/gtkprintbackendtest.c tests/testfilechooser.c diff --git a/po-properties/af.po b/po-properties/af.po index 2f5c40c19f..4774da4dc3 100644 --- a/po-properties/af.po +++ b/po-properties/af.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: gtk+-properties 2.6-branch\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-06-15 20:53-0400\n" +"POT-Creation-Date: 2009-09-30 17:31-0400\n" "PO-Revision-Date: 2004-03-30 17:02+0200\n" "Last-Translator: Zuza Software Foundation \n" "Language-Team: Afrikaans \n" @@ -16,6 +16,16 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +#: gdk-pixbuf/gdk-pixbuf-simple-anim.c:165 +msgid "Loop" +msgstr "" + +#: gdk-pixbuf/gdk-pixbuf-simple-anim.c:166 +#, fuzzy +msgid "Whether the animation should loop when it reaches the end" +msgstr "" +"Of die kleurkieser toegelaat moet word om die ondeursigtigheid te verstel" + #: gdk-pixbuf/gdk-pixbuf.c:89 msgid "Number of Channels" msgstr "Getal kanale" @@ -48,7 +58,7 @@ msgstr "Bisse per monster" msgid "The number of bits per sample" msgstr "Die getal bisse per monster" -#: gdk-pixbuf/gdk-pixbuf.c:132 gtk/gtklayout.c:632 gtk/gtktreeviewcolumn.c:207 +#: gdk-pixbuf/gdk-pixbuf.c:132 gtk/gtklayout.c:632 gtk/gtktreeviewcolumn.c:208 msgid "Width" msgstr "Wydte" @@ -90,12 +100,12 @@ msgstr "Verstekvertoon" msgid "The default display for GDK" msgstr "Die verstekvertoon vir GDK" -#: gdk/gdkpango.c:537 gtk/gtkinvisible.c:86 gtk/gtkmountoperation.c:155 -#: gtk/gtkstatusicon.c:277 gtk/gtkwindow.c:614 +#: gdk/gdkpango.c:538 gtk/gtkinvisible.c:86 gtk/gtkmountoperation.c:176 +#: gtk/gtkstatusicon.c:280 gtk/gtkwindow.c:614 msgid "Screen" msgstr "Skerm" -#: gdk/gdkpango.c:538 +#: gdk/gdkpango.c:539 #, fuzzy msgid "the GdkScreen for the renderer" msgstr "Die model vir die boomaansig" @@ -120,6 +130,11 @@ msgstr "Fontpunte" msgid "The resolution for fonts on the screen" msgstr "Hoe die strekking op die skerm moet bygewerk word" +#: gdk/gdkwindow.c:472 gdk/gdkwindow.c:473 +#, fuzzy +msgid "Cursor" +msgstr "Wyserflonker" + #: gtk/gtkaboutdialog.c:239 #, fuzzy msgid "Program name" @@ -265,7 +280,7 @@ msgid "A unique name for the action." msgstr "n Unieke naam vir die aksie." #: gtk/gtkaction.c:198 gtk/gtkbutton.c:219 gtk/gtkexpander.c:195 -#: gtk/gtkframe.c:105 gtk/gtklabel.c:495 gtk/gtkmenuitem.c:300 +#: gtk/gtkframe.c:105 gtk/gtklabel.c:496 gtk/gtkmenuitem.c:305 #: gtk/gtktoolbutton.c:202 msgid "Label" msgstr "Etiket" @@ -299,34 +314,34 @@ msgstr "Stapelikoon" msgid "The stock icon displayed in widgets representing this action." msgstr "Die stapelikon vertoon in dingesies wat hierdie aksie verteenwoordig." -#: gtk/gtkaction.c:261 gtk/gtkstatusicon.c:250 +#: gtk/gtkaction.c:261 gtk/gtkstatusicon.c:253 #, fuzzy msgid "GIcon" msgstr "Ikon" #: gtk/gtkaction.c:262 gtk/gtkcellrendererpixbuf.c:206 gtk/gtkimage.c:248 -#: gtk/gtkstatusicon.c:251 +#: gtk/gtkstatusicon.c:254 #, fuzzy msgid "The GIcon being displayed" msgstr "Ikonstel wat vertoon moet word" #: gtk/gtkaction.c:282 gtk/gtkcellrendererpixbuf.c:171 gtk/gtkimage.c:230 -#: gtk/gtkprinter.c:172 gtk/gtkstatusicon.c:234 gtk/gtkwindow.c:606 +#: gtk/gtkprinter.c:172 gtk/gtkstatusicon.c:237 gtk/gtkwindow.c:606 #, fuzzy msgid "Icon Name" msgstr "Fontnaam" #: gtk/gtkaction.c:283 gtk/gtkcellrendererpixbuf.c:172 gtk/gtkimage.c:231 -#: gtk/gtkstatusicon.c:235 +#: gtk/gtkstatusicon.c:238 #, fuzzy msgid "The name of the icon from the icon theme" msgstr "Die naam van die geselekteerde font" -#: gtk/gtkaction.c:290 gtk/gtktoolitem.c:176 +#: gtk/gtkaction.c:290 gtk/gtktoolitem.c:192 msgid "Visible when horizontal" msgstr "Sigbaar wanneer horisontaal" -#: gtk/gtkaction.c:291 gtk/gtktoolitem.c:177 +#: gtk/gtkaction.c:291 gtk/gtktoolitem.c:193 msgid "" "Whether the toolbar item is visible when the toolbar is in a horizontal " "orientation." @@ -345,18 +360,18 @@ msgid "" "overflow menu." msgstr "Wanneer WAAR, word leë kieslysinstaners vir hierdie aksie verskuil." -#: gtk/gtkaction.c:314 gtk/gtktoolitem.c:183 +#: gtk/gtkaction.c:314 gtk/gtktoolitem.c:199 msgid "Visible when vertical" msgstr "Sigbaar wanneer vertikaal" -#: gtk/gtkaction.c:315 gtk/gtktoolitem.c:184 +#: gtk/gtkaction.c:315 gtk/gtktoolitem.c:200 msgid "" "Whether the toolbar item is visible when the toolbar is in a vertical " "orientation." msgstr "" "Of die nutsbalkitem sigbaar is wanneer die nutsbalk vertikaal gerig is." -#: gtk/gtkaction.c:322 gtk/gtktoolitem.c:190 +#: gtk/gtkaction.c:322 gtk/gtktoolitem.c:206 msgid "Is important" msgstr "Is belangrik" @@ -377,7 +392,7 @@ msgid "When TRUE, empty menu proxies for this action are hidden." msgstr "Wanneer WAAR, word leë kieslysinstaners vir hierdie aksie verskuil." #: gtk/gtkaction.c:338 gtk/gtkactiongroup.c:177 gtk/gtkcellrenderer.c:193 -#: gtk/gtkwidget.c:523 +#: gtk/gtkwidget.c:525 msgid "Sensitive" msgstr "Sensitief" @@ -385,8 +400,8 @@ msgstr "Sensitief" msgid "Whether the action is enabled." msgstr "Of die aksie in werking gestel is." -#: gtk/gtkaction.c:345 gtk/gtkactiongroup.c:184 gtk/gtkstatusicon.c:293 -#: gtk/gtktreeviewcolumn.c:191 gtk/gtkwidget.c:516 +#: gtk/gtkaction.c:345 gtk/gtkactiongroup.c:184 gtk/gtkstatusicon.c:296 +#: gtk/gtktreeviewcolumn.c:192 gtk/gtkwidget.c:518 msgid "Visible" msgstr "Sigbaar" @@ -418,6 +433,24 @@ msgstr "Of die aksiegroep in werking gestel is." msgid "Whether the action group is visible." msgstr "Of die aksiegroep sigbaar is." +#: gtk/gtkactivatable.c:304 +#, fuzzy +msgid "Related Action" +msgstr "Aksie" + +#: gtk/gtkactivatable.c:305 +msgid "The action this activatable will activate and receive updates from" +msgstr "" + +#: gtk/gtkactivatable.c:327 +msgid "Use Action Appearance" +msgstr "" + +#: gtk/gtkactivatable.c:328 +#, fuzzy +msgid "Whether to use the related actions appearance properties" +msgstr "Of die etiketteks met die muis gekies kan word" + #: gtk/gtkadjustment.c:93 gtk/gtkcellrendererprogress.c:128 #: gtk/gtkscalebutton.c:206 gtk/gtkspinbutton.c:269 msgid "Value" @@ -563,7 +596,7 @@ msgstr "Pyltjieskadu" msgid "Appearance of the shadow surrounding the arrow" msgstr "Vertoon van die skadu wat die pyltjie omring" -#: gtk/gtkarrow.c:92 gtk/gtkmenu.c:689 gtk/gtkmenuitem.c:363 +#: gtk/gtkarrow.c:92 gtk/gtkmenu.c:711 gtk/gtkmenuitem.c:368 #, fuzzy msgid "Arrow Scaling" msgstr "Ryspasiëring" @@ -671,44 +704,44 @@ msgstr "Bladsyinkrement" msgid "Whether all required fields on the page have been filled out" msgstr "" -#: gtk/gtkbbox.c:99 +#: gtk/gtkbbox.c:101 msgid "Minimum child width" msgstr "minimum kindwydte" -#: gtk/gtkbbox.c:100 +#: gtk/gtkbbox.c:102 msgid "Minimum width of buttons inside the box" msgstr "minimum wydte van knoppies in die kassie" -#: gtk/gtkbbox.c:108 +#: gtk/gtkbbox.c:110 msgid "Minimum child height" msgstr "minimum kindhoogte" -#: gtk/gtkbbox.c:109 +#: gtk/gtkbbox.c:111 msgid "Minimum height of buttons inside the box" msgstr "minimum hoogte van knoppies in die kassie" -#: gtk/gtkbbox.c:117 +#: gtk/gtkbbox.c:119 msgid "Child internal width padding" msgstr "Kind-binnewydteopvulling" -#: gtk/gtkbbox.c:118 +#: gtk/gtkbbox.c:120 msgid "Amount to increase child's size on either side" msgstr "Hoeveelheid om kind se grootte aan ieder kant te vergroot" -#: gtk/gtkbbox.c:126 +#: gtk/gtkbbox.c:128 msgid "Child internal height padding" msgstr "Kind-binnehoogteopvulling" -#: gtk/gtkbbox.c:127 +#: gtk/gtkbbox.c:129 msgid "Amount to increase child's size on the top and bottom" msgstr "" "Hoeveelheid wat kind se grootte aan bo- en onderkant vergroot moet word" -#: gtk/gtkbbox.c:135 +#: gtk/gtkbbox.c:137 msgid "Layout style" msgstr "Uitlegstyl" -#: gtk/gtkbbox.c:136 +#: gtk/gtkbbox.c:138 msgid "" "How to layout the buttons in the box. Possible values are default, spread, " "edge, start and end" @@ -716,11 +749,11 @@ msgstr "" "Hoe om die knoppies in die kassie uit te lê. Moontlike waardes is default " "(verstek), spread (versprei), \vedge (rand), start (begin) en end (einde)" -#: gtk/gtkbbox.c:144 +#: gtk/gtkbbox.c:146 msgid "Secondary" msgstr "Sekondêre" -#: gtk/gtkbbox.c:145 +#: gtk/gtkbbox.c:147 msgid "" "If TRUE, the child appears in a secondary group of children, suitable for, e." "g., help buttons" @@ -728,8 +761,8 @@ msgstr "" "Indien WAAR, verskyn die kind in 'n sekondêre groep kinders, geskik vir " "byvoorbeeld hulpknoppies" -#: gtk/gtkbox.c:130 gtk/gtkexpander.c:219 gtk/gtkiconview.c:664 -#: gtk/gtktreeviewcolumn.c:216 +#: gtk/gtkbox.c:130 gtk/gtkexpander.c:219 gtk/gtkiconview.c:665 +#: gtk/gtktreeviewcolumn.c:217 msgid "Spacing" msgstr "Spasiëring" @@ -747,7 +780,7 @@ msgid "Whether the children should all be the same size" msgstr "Of die kinders almal dieselfde grootte moet wees" #: gtk/gtkbox.c:148 gtk/gtkpreview.c:101 gtk/gtktoolbar.c:565 -#: gtk/gtktreeviewcolumn.c:272 +#: gtk/gtktreeviewcolumn.c:273 msgid "Expand" msgstr "Uitvou" @@ -812,13 +845,13 @@ msgstr "" "Teks van die etiketdingesie binne-in die knoppie, indien die knoppie 'n " "etiketdingesie bevat" -#: gtk/gtkbutton.c:227 gtk/gtkexpander.c:203 gtk/gtklabel.c:516 -#: gtk/gtkmenuitem.c:315 gtk/gtktoolbutton.c:209 +#: gtk/gtkbutton.c:227 gtk/gtkexpander.c:203 gtk/gtklabel.c:517 +#: gtk/gtkmenuitem.c:320 gtk/gtktoolbutton.c:209 msgid "Use underline" msgstr "Gebruik onderstreep" -#: gtk/gtkbutton.c:228 gtk/gtkexpander.c:204 gtk/gtklabel.c:517 -#: gtk/gtkmenuitem.c:316 +#: gtk/gtkbutton.c:228 gtk/gtkexpander.c:204 gtk/gtklabel.c:518 +#: gtk/gtkmenuitem.c:321 msgid "" "If set, an underline in the text indicates the next character should be used " "for the mnemonic accelerator key" @@ -837,7 +870,7 @@ msgstr "" "Indien gestel, word die etiket gebruik om 'n stapelitem te kies in plaas " "daarvan om vertoon te word" -#: gtk/gtkbutton.c:243 gtk/gtkcombobox.c:789 gtk/gtkfilechooserbutton.c:393 +#: gtk/gtkbutton.c:243 gtk/gtkcombobox.c:791 gtk/gtkfilechooserbutton.c:393 msgid "Focus on click" msgstr "Fokus op kliek" @@ -931,7 +964,7 @@ msgid "" "rectangle" msgstr "" -#: gtk/gtkbutton.c:485 gtk/gtkentry.c:658 gtk/gtkentry.c:1682 +#: gtk/gtkbutton.c:485 gtk/gtkentry.c:689 gtk/gtkentry.c:1713 #, fuzzy msgid "Inner Border" msgstr "Oortjiegrens" @@ -1168,40 +1201,40 @@ msgstr "Selagtergrondstel" msgid "Whether this tag affects the cell background color" msgstr "Of hierdie merker 'n uitwerking op die selagtergrondkleur het" -#: gtk/gtkcellrendereraccel.c:113 +#: gtk/gtkcellrendereraccel.c:114 #, fuzzy msgid "Accelerator key" msgstr "Versnellerdingesie" -#: gtk/gtkcellrendereraccel.c:114 +#: gtk/gtkcellrendereraccel.c:115 #, fuzzy msgid "The keyval of the accelerator" msgstr "Die waarde van die aanpassing" -#: gtk/gtkcellrendereraccel.c:130 +#: gtk/gtkcellrendereraccel.c:131 #, fuzzy msgid "Accelerator modifiers" msgstr "Versnellerdingesie" -#: gtk/gtkcellrendereraccel.c:131 +#: gtk/gtkcellrendereraccel.c:132 msgid "The modifier mask of the accelerator" msgstr "" -#: gtk/gtkcellrendereraccel.c:148 +#: gtk/gtkcellrendereraccel.c:149 #, fuzzy msgid "Accelerator keycode" msgstr "Versnellerdingesie" -#: gtk/gtkcellrendereraccel.c:149 +#: gtk/gtkcellrendereraccel.c:150 msgid "The hardware keycode of the accelerator" msgstr "" -#: gtk/gtkcellrendereraccel.c:168 +#: gtk/gtkcellrendereraccel.c:169 #, fuzzy msgid "Accelerator Mode" msgstr "Versnellerdingesie" -#: gtk/gtkcellrendereraccel.c:169 +#: gtk/gtkcellrendereraccel.c:170 #, fuzzy msgid "The type of accelerators" msgstr "Die soort boodskap" @@ -1256,7 +1289,7 @@ msgstr "Pixbuf-uitvouer geslote" msgid "Pixbuf for closed expander" msgstr "Pixbuf vir geslote uitvouer" -#: gtk/gtkcellrendererpixbuf.c:135 gtk/gtkimage.c:172 gtk/gtkstatusicon.c:226 +#: gtk/gtkcellrendererpixbuf.c:135 gtk/gtkimage.c:172 gtk/gtkstatusicon.c:229 msgid "Stock ID" msgstr "Stapel-ID" @@ -1265,7 +1298,7 @@ msgid "The stock ID of the stock icon to render" msgstr "Die stapel-ID van die stapelikon om weer te gee" #: gtk/gtkcellrendererpixbuf.c:143 gtk/gtkrecentmanager.c:245 -#: gtk/gtkstatusicon.c:267 +#: gtk/gtkstatusicon.c:270 msgid "Size" msgstr "Grootte" @@ -1300,8 +1333,8 @@ msgid "Value of the progress bar" msgstr "Teks wat in die vorderingstaaf vertoon moet word" #: gtk/gtkcellrendererprogress.c:146 gtk/gtkcellrenderertext.c:195 -#: gtk/gtkentry.c:701 gtk/gtkmessagedialog.c:153 gtk/gtkprogressbar.c:184 -#: gtk/gtktextbuffer.c:198 +#: gtk/gtkentry.c:732 gtk/gtkentrybuffer.c:353 gtk/gtkmessagedialog.c:153 +#: gtk/gtkprogressbar.c:184 gtk/gtktextbuffer.c:198 msgid "Text" msgstr "Teks" @@ -1342,7 +1375,7 @@ msgid "The vertical text alignment, from 0 (top) to 1 (bottom)." msgstr "Die vertikale belyning, van 0 (bo) na 1 (onder)" #: gtk/gtkcellrendererprogress.c:221 gtk/gtkiconview.c:729 -#: gtk/gtkorientable.c:74 gtk/gtkprogressbar.c:126 gtk/gtkstatusicon.c:325 +#: gtk/gtkorientable.c:74 gtk/gtkprogressbar.c:126 gtk/gtkstatusicon.c:328 #: gtk/gtktrayicon-x11.c:110 msgid "Orientation" msgstr "Oriëntering" @@ -1390,7 +1423,7 @@ msgstr "Markering" msgid "Marked up text to render" msgstr "Gemarkeerde teks om weer te gee" -#: gtk/gtkcellrenderertext.c:211 gtk/gtklabel.c:502 +#: gtk/gtkcellrenderertext.c:211 gtk/gtklabel.c:503 msgid "Attributes" msgstr "Attribute" @@ -1438,12 +1471,12 @@ msgstr "Voorgrondkleur" msgid "Foreground color as a GdkColor" msgstr "Voorgrondkleur as 'n GdkColor" -#: gtk/gtkcellrenderertext.c:261 gtk/gtkentry.c:625 gtk/gtktexttag.c:251 -#: gtk/gtktextview.c:573 +#: gtk/gtkcellrenderertext.c:261 gtk/gtkentry.c:656 gtk/gtktexttag.c:251 +#: gtk/gtktextview.c:574 msgid "Editable" msgstr "Redigeerbaar" -#: gtk/gtkcellrenderertext.c:262 gtk/gtktexttag.c:252 gtk/gtktextview.c:574 +#: gtk/gtkcellrenderertext.c:262 gtk/gtktexttag.c:252 gtk/gtktextview.c:575 msgid "Whether the text can be modified by the user" msgstr "Of die teks deur die gebruiker gewysig kan word" @@ -1550,7 +1583,7 @@ msgstr "" "gebruik wanneer die teks verbeeld word. As jy nie hierdie parameter verstaan " "nie, het jy dit waarskynlik nie nodig nie" -#: gtk/gtkcellrenderertext.c:411 gtk/gtklabel.c:627 gtk/gtkprogressbar.c:206 +#: gtk/gtkcellrenderertext.c:411 gtk/gtklabel.c:628 gtk/gtkprogressbar.c:206 msgid "Ellipsize" msgstr "" @@ -1561,12 +1594,12 @@ msgid "" msgstr "" #: gtk/gtkcellrenderertext.c:431 gtk/gtkfilechooserbutton.c:421 -#: gtk/gtklabel.c:647 +#: gtk/gtklabel.c:648 #, fuzzy msgid "Width In Characters" msgstr "Wydte in karakters" -#: gtk/gtkcellrenderertext.c:432 gtk/gtklabel.c:648 +#: gtk/gtkcellrenderertext.c:432 gtk/gtklabel.c:649 msgid "The desired width of the label, in characters" msgstr "" @@ -1580,7 +1613,7 @@ msgid "" "have enough room to display the entire string" msgstr "" -#: gtk/gtkcellrenderertext.c:470 gtk/gtkcombobox.c:678 +#: gtk/gtkcellrenderertext.c:470 gtk/gtkcombobox.c:680 msgid "Wrap width" msgstr "Vouwydte" @@ -1589,7 +1622,7 @@ msgstr "Vouwydte" msgid "The width at which the text is wrapped" msgstr "Die posisie waarin die huidige waarde vertoon word" -#: gtk/gtkcellrenderertext.c:491 gtk/gtktreeviewcolumn.c:297 +#: gtk/gtkcellrenderertext.c:491 gtk/gtktreeviewcolumn.c:298 msgid "Alignment" msgstr "Gerigtheid" @@ -1796,7 +1829,7 @@ msgstr "Aanduierspasiëring" msgid "Spacing around check or radio indicator" msgstr "Spasiëring rondom merkie- of klinkaanduier" -#: gtk/gtkcheckmenuitem.c:98 gtk/gtkmenu.c:500 gtk/gtktoggleaction.c:119 +#: gtk/gtkcheckmenuitem.c:98 gtk/gtkmenu.c:501 gtk/gtktoggleaction.c:119 #: gtk/gtktogglebutton.c:115 gtk/gtktoggletoolbutton.c:114 msgid "Active" msgstr "Aktief" @@ -1830,7 +1863,8 @@ msgid "Whether or not to give the color an alpha value" msgstr "Of die kleur 'n alfawaarde gegee moet word" #: gtk/gtkcolorbutton.c:186 gtk/gtkfilechooserbutton.c:407 -#: gtk/gtkfontbutton.c:142 gtk/gtkprintjob.c:116 gtk/gtktreeviewcolumn.c:264 +#: gtk/gtkfontbutton.c:142 gtk/gtkprintjob.c:116 gtk/gtkstatusicon.c:424 +#: gtk/gtktreeviewcolumn.c:265 msgid "Title" msgstr "Titel" @@ -1970,71 +2004,71 @@ msgstr "Waarde in lys" msgid "Whether entered values must already be present in the list" msgstr "Of ingetikte waardes reeds in die lys teenwoordig moet wees" -#: gtk/gtkcombobox.c:661 +#: gtk/gtkcombobox.c:663 msgid "ComboBox model" msgstr "Kombinasiekas-model" -#: gtk/gtkcombobox.c:662 +#: gtk/gtkcombobox.c:664 msgid "The model for the combo box" msgstr "Die model van die kombinasiekas" -#: gtk/gtkcombobox.c:679 +#: gtk/gtkcombobox.c:681 #, fuzzy msgid "Wrap width for laying out the items in a grid" msgstr "Vouwydte vir die uitlê van items op 'n rooster" -#: gtk/gtkcombobox.c:701 +#: gtk/gtkcombobox.c:703 msgid "Row span column" msgstr "Ryspankolom" -#: gtk/gtkcombobox.c:702 +#: gtk/gtkcombobox.c:704 msgid "TreeModel column containing the row span values" msgstr "Boommodel-kolom wat die ryspanwaarde bevat" -#: gtk/gtkcombobox.c:723 +#: gtk/gtkcombobox.c:725 msgid "Column span column" msgstr "Kolomspankolom" -#: gtk/gtkcombobox.c:724 +#: gtk/gtkcombobox.c:726 msgid "TreeModel column containing the column span values" msgstr "Boommodel-kolom wat die kolomspanwaarde bevat" -#: gtk/gtkcombobox.c:745 +#: gtk/gtkcombobox.c:747 msgid "Active item" msgstr "Aktiewe item" -#: gtk/gtkcombobox.c:746 +#: gtk/gtkcombobox.c:748 msgid "The item which is currently active" msgstr "Die item wat tans aktief is" -#: gtk/gtkcombobox.c:765 gtk/gtkuimanager.c:222 +#: gtk/gtkcombobox.c:767 gtk/gtkuimanager.c:222 msgid "Add tearoffs to menus" msgstr "Voeg afskeuritems by die kieslyste" -#: gtk/gtkcombobox.c:766 +#: gtk/gtkcombobox.c:768 #, fuzzy msgid "Whether dropdowns should have a tearoff menu item" msgstr "Of oortjies eenvormige groottes moet hê" -#: gtk/gtkcombobox.c:781 gtk/gtkentry.c:650 +#: gtk/gtkcombobox.c:783 gtk/gtkentry.c:681 msgid "Has Frame" msgstr "Het raam" -#: gtk/gtkcombobox.c:782 +#: gtk/gtkcombobox.c:784 #, fuzzy msgid "Whether the combo box draws a frame around the child" msgstr "Of die kolom rondom die koppe hersorteer kan word" -#: gtk/gtkcombobox.c:790 +#: gtk/gtkcombobox.c:792 #, fuzzy msgid "Whether the combo box grabs focus when it is clicked with the mouse" msgstr "Of 'n knoppie die fokus gryp wanneer dit met die muis gekliek word" -#: gtk/gtkcombobox.c:805 gtk/gtkmenu.c:555 +#: gtk/gtkcombobox.c:807 gtk/gtkmenu.c:556 msgid "Tearoff Title" msgstr "Afskeurtitel" -#: gtk/gtkcombobox.c:806 +#: gtk/gtkcombobox.c:808 #, fuzzy msgid "" "A title that may be displayed by the window manager when the popup is torn-" @@ -2043,51 +2077,51 @@ msgstr "" "'n Titel wat deur die vensterbestuurder vertoon kan word wanneer hierdie " "kieslys afgeskeur word" -#: gtk/gtkcombobox.c:823 +#: gtk/gtkcombobox.c:825 #, fuzzy msgid "Popup shown" msgstr "Fokus op reëlwydte" -#: gtk/gtkcombobox.c:824 +#: gtk/gtkcombobox.c:826 #, fuzzy msgid "Whether the combo's dropdown is shown" msgstr "Of die grens vertoon moet word of nie" -#: gtk/gtkcombobox.c:840 +#: gtk/gtkcombobox.c:842 msgid "Button Sensitivity" msgstr "" -#: gtk/gtkcombobox.c:841 +#: gtk/gtkcombobox.c:843 #, fuzzy msgid "Whether the dropdown button is sensitive when the model is empty" msgstr "Of 'n knoppie die fokus gryp wanneer dit met die muis gekliek word" -#: gtk/gtkcombobox.c:848 +#: gtk/gtkcombobox.c:850 msgid "Appears as list" msgstr "" -#: gtk/gtkcombobox.c:849 +#: gtk/gtkcombobox.c:851 #, fuzzy msgid "Whether dropdowns should look like lists rather than menus" msgstr "Of die vouers in plaas van die lêers gekies moet word" -#: gtk/gtkcombobox.c:865 +#: gtk/gtkcombobox.c:867 #, fuzzy msgid "Arrow Size" msgstr "Pyltjierigting" -#: gtk/gtkcombobox.c:866 +#: gtk/gtkcombobox.c:868 #, fuzzy msgid "The minimum size of the arrow in the combo box" msgstr "Die model van die kombinasiekas" -#: gtk/gtkcombobox.c:881 gtk/gtkentry.c:750 gtk/gtkhandlebox.c:174 +#: gtk/gtkcombobox.c:883 gtk/gtkentry.c:781 gtk/gtkhandlebox.c:174 #: gtk/gtkmenubar.c:194 gtk/gtkstatusbar.c:186 gtk/gtktoolbar.c:623 #: gtk/gtkviewport.c:122 msgid "Shadow type" msgstr "Arseringsoort" -#: gtk/gtkcombobox.c:882 +#: gtk/gtkcombobox.c:884 #, fuzzy msgid "Which kind of shadow to draw around the combo box" msgstr "Wydte van grens rondom die oortjie-etikette" @@ -2164,7 +2198,7 @@ msgstr "Het skeier" msgid "The dialog has a separator bar above its buttons" msgstr "Die dialoog het 'n skeierstafie bokant sy knoppies" -#: gtk/gtkdialog.c:191 +#: gtk/gtkdialog.c:191 gtk/gtkinfobar.c:439 msgid "Content area border" msgstr "Inhoudstreekgrens" @@ -2172,7 +2206,7 @@ msgstr "Inhoudstreekgrens" msgid "Width of border around the main dialog area" msgstr "Wydte van grens rondom die hoofdialoogstreek" -#: gtk/gtkdialog.c:209 +#: gtk/gtkdialog.c:209 gtk/gtkinfobar.c:456 #, fuzzy msgid "Content area spacing" msgstr "Onderkantopvulling" @@ -2182,15 +2216,15 @@ msgstr "Onderkantopvulling" msgid "Spacing between elements of the main dialog area" msgstr "Ruimte tussen waardeteks en die skuifknoppie/trog-streek" -#: gtk/gtkdialog.c:217 +#: gtk/gtkdialog.c:217 gtk/gtkinfobar.c:472 msgid "Button spacing" msgstr "Knoppiespasiëring" -#: gtk/gtkdialog.c:218 +#: gtk/gtkdialog.c:218 gtk/gtkinfobar.c:473 msgid "Spacing between buttons" msgstr "Spasiëring tussen knoppies" -#: gtk/gtkdialog.c:226 +#: gtk/gtkdialog.c:226 gtk/gtkinfobar.c:488 msgid "Action area border" msgstr "Aksiestreekgrens" @@ -2199,43 +2233,52 @@ msgid "Width of border around the button area at the bottom of the dialog" msgstr "" "Wydte van grens rondom die knoppiestreek aan die onderkant van die dialoog" -#: gtk/gtkentry.c:605 gtk/gtklabel.c:590 +#: gtk/gtkentry.c:628 +#, fuzzy +msgid "Text Buffer" +msgstr "Buffer" + +#: gtk/gtkentry.c:629 +msgid "Text buffer object which actually stores entry text" +msgstr "" + +#: gtk/gtkentry.c:636 gtk/gtklabel.c:591 msgid "Cursor Position" msgstr "Wyserposisie" -#: gtk/gtkentry.c:606 gtk/gtklabel.c:591 +#: gtk/gtkentry.c:637 gtk/gtklabel.c:592 msgid "The current position of the insertion cursor in chars" msgstr "Die huidige posisie van die invoegingswyser in karakters" -#: gtk/gtkentry.c:615 gtk/gtklabel.c:600 +#: gtk/gtkentry.c:646 gtk/gtklabel.c:601 msgid "Selection Bound" msgstr "Seleksiegrens" -#: gtk/gtkentry.c:616 gtk/gtklabel.c:601 +#: gtk/gtkentry.c:647 gtk/gtklabel.c:602 msgid "" "The position of the opposite end of the selection from the cursor in chars" msgstr "" "Die posisie van die oorkantste punt van die seleksie van die wyser in " "karakters" -#: gtk/gtkentry.c:626 +#: gtk/gtkentry.c:657 msgid "Whether the entry contents can be edited" msgstr "Of die inskrywingsinhoud geredigeer kan word" -#: gtk/gtkentry.c:633 +#: gtk/gtkentry.c:664 gtk/gtkentrybuffer.c:383 msgid "Maximum length" msgstr "maksimum lengte" -#: gtk/gtkentry.c:634 +#: gtk/gtkentry.c:665 gtk/gtkentrybuffer.c:384 msgid "Maximum number of characters for this entry. Zero if no maximum" msgstr "" "Maksimum getal karakters vir hierdie inskrywing. Nul indien geen maksimum" -#: gtk/gtkentry.c:642 +#: gtk/gtkentry.c:673 msgid "Visibility" msgstr "Sigbaarheid" -#: gtk/gtkentry.c:643 +#: gtk/gtkentry.c:674 msgid "" "FALSE displays the \"invisible char\" instead of the actual text (password " "mode)" @@ -2243,30 +2286,30 @@ msgstr "" "VALS vertoon die \"onsigbare karakter\" in plaas van die werklike teks " "(wagwoordmodus)" -#: gtk/gtkentry.c:651 +#: gtk/gtkentry.c:682 msgid "FALSE removes outside bevel from entry" msgstr "VALS verwyder buiteskuinskant uit inskrywing" -#: gtk/gtkentry.c:659 +#: gtk/gtkentry.c:690 msgid "" "Border between text and frame. Overrides the inner-border style property" msgstr "" -#: gtk/gtkentry.c:666 gtk/gtkentry.c:1232 +#: gtk/gtkentry.c:697 gtk/gtkentry.c:1263 msgid "Invisible character" msgstr "Onsigbare karakter" -#: gtk/gtkentry.c:667 gtk/gtkentry.c:1233 +#: gtk/gtkentry.c:698 gtk/gtkentry.c:1264 msgid "The character to use when masking entry contents (in \"password mode\")" msgstr "" "Die karakter om te gebruik wanneer inskrywingsinhoud verberg word (in " "\"wagwoordmodus\")" -#: gtk/gtkentry.c:674 +#: gtk/gtkentry.c:705 msgid "Activates default" msgstr "Aktiveer verstek" -#: gtk/gtkentry.c:675 +#: gtk/gtkentry.c:706 msgid "" "Whether to activate the default widget (such as the default button in a " "dialog) when Enter is pressed" @@ -2274,103 +2317,103 @@ msgstr "" "Of die verstekdingesie (soos die verstekknoppie in 'n dialoog) geaktiveer " "moet word wanneer ENTER gedruk word" -#: gtk/gtkentry.c:681 +#: gtk/gtkentry.c:712 msgid "Width in chars" msgstr "Wydte in karakters" -#: gtk/gtkentry.c:682 +#: gtk/gtkentry.c:713 msgid "Number of characters to leave space for in the entry" msgstr "Getal karakters om ruimte voor in die inskrywing te laat" -#: gtk/gtkentry.c:691 +#: gtk/gtkentry.c:722 msgid "Scroll offset" msgstr "Rolverplasing" -#: gtk/gtkentry.c:692 +#: gtk/gtkentry.c:723 msgid "Number of pixels of the entry scrolled off the screen to the left" msgstr "Getal pixels van die inskrywing wat links van die skerm af rol" -#: gtk/gtkentry.c:702 +#: gtk/gtkentry.c:733 msgid "The contents of the entry" msgstr "Die inhoud van die inskrywing" -#: gtk/gtkentry.c:717 gtk/gtkmisc.c:73 +#: gtk/gtkentry.c:748 gtk/gtkmisc.c:73 msgid "X align" msgstr "x-align" -#: gtk/gtkentry.c:718 gtk/gtkmisc.c:74 +#: gtk/gtkentry.c:749 gtk/gtkmisc.c:74 #, fuzzy msgid "" "The horizontal alignment, from 0 (left) to 1 (right). Reversed for RTL " "layouts." msgstr "Die horisontale belyning, van 0 (links) na 1 (regs)" -#: gtk/gtkentry.c:734 +#: gtk/gtkentry.c:765 #, fuzzy msgid "Truncate multiline" msgstr "Selekteer meervoudig" -#: gtk/gtkentry.c:735 +#: gtk/gtkentry.c:766 #, fuzzy msgid "Whether to truncate multiline pastes to one line." msgstr "Of meervoudige lêers geselekteer mag word" -#: gtk/gtkentry.c:751 +#: gtk/gtkentry.c:782 msgid "Which kind of shadow to draw around the entry when has-frame is set" msgstr "" -#: gtk/gtkentry.c:766 gtk/gtktextview.c:653 +#: gtk/gtkentry.c:797 gtk/gtktextview.c:654 msgid "Overwrite mode" msgstr "Oorheenskryfmodus" -#: gtk/gtkentry.c:767 +#: gtk/gtkentry.c:798 #, fuzzy msgid "Whether new text overwrites existing text" msgstr "Of teks wat ingetik word, bestaande teks oorheenskryf" -#: gtk/gtkentry.c:781 +#: gtk/gtkentry.c:812 gtk/gtkentrybuffer.c:368 #, fuzzy msgid "Text length" msgstr "Teks-x-gerigtheid" -#: gtk/gtkentry.c:782 +#: gtk/gtkentry.c:813 msgid "Length of the text currently in the entry" msgstr "" -#: gtk/gtkentry.c:797 +#: gtk/gtkentry.c:828 #, fuzzy msgid "Invisible char set" msgstr "Onsigbaar-stel" -#: gtk/gtkentry.c:798 +#: gtk/gtkentry.c:829 #, fuzzy msgid "Whether the invisible char has been set" msgstr "Of die aksiegroep in werking gestel is." -#: gtk/gtkentry.c:816 +#: gtk/gtkentry.c:847 msgid "Caps Lock warning" msgstr "" -#: gtk/gtkentry.c:817 +#: gtk/gtkentry.c:848 msgid "Whether password entries will show a warning when Caps Lock is on" msgstr "" -#: gtk/gtkentry.c:831 +#: gtk/gtkentry.c:862 #, fuzzy msgid "Progress Fraction" msgstr "Fraksie" -#: gtk/gtkentry.c:832 +#: gtk/gtkentry.c:863 #, fuzzy msgid "The current fraction of the task that's been completed" msgstr "Die fraksie van die totale werk wat al voltooi is" -#: gtk/gtkentry.c:849 +#: gtk/gtkentry.c:880 #, fuzzy msgid "Progress Pulse Step" msgstr "Polsstap" -#: gtk/gtkentry.c:850 +#: gtk/gtkentry.c:881 #, fuzzy msgid "" "The fraction of total entry width to move the progress bouncing block for " @@ -2379,229 +2422,238 @@ msgstr "" "Die fraksie van die totale vordering wat die wipblok beweeg moet word " "wanneer dit gepols word" -#: gtk/gtkentry.c:866 +#: gtk/gtkentry.c:897 #, fuzzy msgid "Primary pixbuf" msgstr "Pixbuf" -#: gtk/gtkentry.c:867 +#: gtk/gtkentry.c:898 #, fuzzy msgid "Primary pixbuf for the entry" msgstr "Pixbuf vir oop uitvouer" -#: gtk/gtkentry.c:881 +#: gtk/gtkentry.c:912 #, fuzzy msgid "Secondary pixbuf" msgstr "Sekondêre" -#: gtk/gtkentry.c:882 +#: gtk/gtkentry.c:913 #, fuzzy msgid "Secondary pixbuf for the entry" msgstr "Sekondêre vorentoestapper" -#: gtk/gtkentry.c:896 +#: gtk/gtkentry.c:927 msgid "Primary stock ID" msgstr "" -#: gtk/gtkentry.c:897 +#: gtk/gtkentry.c:928 msgid "Stock ID for primary icon" msgstr "" -#: gtk/gtkentry.c:911 +#: gtk/gtkentry.c:942 #, fuzzy msgid "Secondary stock ID" msgstr "Sekondêre" -#: gtk/gtkentry.c:912 +#: gtk/gtkentry.c:943 msgid "Stock ID for secondary icon" msgstr "" -#: gtk/gtkentry.c:926 -#, fuzzy -msgid "Primary icon name" -msgstr "Fontnaam" - -#: gtk/gtkentry.c:927 -msgid "Icon name for primary icon" -msgstr "" - -#: gtk/gtkentry.c:941 -#, fuzzy -msgid "Secondary icon name" -msgstr "Sekondêre" - -#: gtk/gtkentry.c:942 -msgid "Icon name for secondary icon" -msgstr "" - -#: gtk/gtkentry.c:956 -msgid "Primary GIcon" -msgstr "" - #: gtk/gtkentry.c:957 #, fuzzy +msgid "Primary icon name" +msgstr "Fontnaam" + +#: gtk/gtkentry.c:958 +msgid "Icon name for primary icon" +msgstr "" + +#: gtk/gtkentry.c:972 +#, fuzzy +msgid "Secondary icon name" +msgstr "Sekondêre" + +#: gtk/gtkentry.c:973 +msgid "Icon name for secondary icon" +msgstr "" + +#: gtk/gtkentry.c:987 +msgid "Primary GIcon" +msgstr "" + +#: gtk/gtkentry.c:988 +#, fuzzy msgid "GIcon for primary icon" msgstr "Ikon vir die venster" -#: gtk/gtkentry.c:971 +#: gtk/gtkentry.c:1002 #, fuzzy msgid "Secondary GIcon" msgstr "Sekondêre" -#: gtk/gtkentry.c:972 +#: gtk/gtkentry.c:1003 msgid "GIcon for secondary icon" msgstr "" -#: gtk/gtkentry.c:986 +#: gtk/gtkentry.c:1017 #, fuzzy msgid "Primary storage type" msgstr "Bergsoort" -#: gtk/gtkentry.c:987 +#: gtk/gtkentry.c:1018 #, fuzzy msgid "The representation being used for primary icon" msgstr "Die voorstelling wat vir die beelddata gebruik word" -#: gtk/gtkentry.c:1002 +#: gtk/gtkentry.c:1033 #, fuzzy msgid "Secondary storage type" msgstr "Sekondêre vorentoestapper" -#: gtk/gtkentry.c:1003 +#: gtk/gtkentry.c:1034 #, fuzzy msgid "The representation being used for secondary icon" msgstr "Die voorstelling wat vir die beelddata gebruik word" -#: gtk/gtkentry.c:1024 +#: gtk/gtkentry.c:1055 msgid "Primary icon activatable" msgstr "" -#: gtk/gtkentry.c:1025 +#: gtk/gtkentry.c:1056 #, fuzzy msgid "Whether the primary icon is activatable" msgstr "Of die aksie in werking gestel is." -#: gtk/gtkentry.c:1045 +#: gtk/gtkentry.c:1076 #, fuzzy msgid "Secondary icon activatable" msgstr "Sekondêrewyser-kleur" -#: gtk/gtkentry.c:1046 +#: gtk/gtkentry.c:1077 #, fuzzy msgid "Whether the secondary icon is activatable" msgstr "Of die aksie in werking gestel is." -#: gtk/gtkentry.c:1068 +#: gtk/gtkentry.c:1099 #, fuzzy msgid "Primary icon sensitive" msgstr "Vertoon die sel" -#: gtk/gtkentry.c:1069 +#: gtk/gtkentry.c:1100 #, fuzzy msgid "Whether the primary icon is sensitive" msgstr "Of die lysitem-passing kassensitief is" -#: gtk/gtkentry.c:1090 +#: gtk/gtkentry.c:1121 #, fuzzy msgid "Secondary icon sensitive" msgstr "Sekondêre" -#: gtk/gtkentry.c:1091 +#: gtk/gtkentry.c:1122 #, fuzzy msgid "Whether the secondary icon is sensitive" msgstr "Of die aksie in werking gestel is." -#: gtk/gtkentry.c:1107 +#: gtk/gtkentry.c:1138 #, fuzzy msgid "Primary icon tooltip text" msgstr "Vertoon die sel" -#: gtk/gtkentry.c:1108 gtk/gtkentry.c:1144 +#: gtk/gtkentry.c:1139 gtk/gtkentry.c:1175 #, fuzzy msgid "The contents of the tooltip on the primary icon" msgstr "Die inhoud van die inskrywing" -#: gtk/gtkentry.c:1124 +#: gtk/gtkentry.c:1155 #, fuzzy msgid "Secondary icon tooltip text" msgstr "Sekondêrewyser-kleur" -#: gtk/gtkentry.c:1125 gtk/gtkentry.c:1163 +#: gtk/gtkentry.c:1156 gtk/gtkentry.c:1194 #, fuzzy msgid "The contents of the tooltip on the secondary icon" msgstr "Die inhoud van die inskrywing" -#: gtk/gtkentry.c:1143 +#: gtk/gtkentry.c:1174 #, fuzzy msgid "Primary icon tooltip markup" msgstr "Fontnaam" -#: gtk/gtkentry.c:1162 +#: gtk/gtkentry.c:1193 #, fuzzy msgid "Secondary icon tooltip markup" msgstr "Sekondêre" -#: gtk/gtkentry.c:1182 gtk/gtktextview.c:681 +#: gtk/gtkentry.c:1213 gtk/gtktextview.c:682 #, fuzzy msgid "IM module" msgstr "Verstekwydte" -#: gtk/gtkentry.c:1183 gtk/gtktextview.c:682 +#: gtk/gtkentry.c:1214 gtk/gtktextview.c:683 #, fuzzy msgid "Which IM module should be used" msgstr "Of 'n palet gebruik moet word" -#: gtk/gtkentry.c:1197 +#: gtk/gtkentry.c:1228 #, fuzzy msgid "Icon Prelight" msgstr "Hoogte" -#: gtk/gtkentry.c:1198 +#: gtk/gtkentry.c:1229 #, fuzzy msgid "Whether activatable icons should prelight when hovered" msgstr "Of oortjies vertoon moet word of nie" -#: gtk/gtkentry.c:1211 +#: gtk/gtkentry.c:1242 #, fuzzy msgid "Progress Border" msgstr "Troggrens" -#: gtk/gtkentry.c:1212 +#: gtk/gtkentry.c:1243 #, fuzzy msgid "Border around the progress bar" msgstr "Teks wat in die vorderingstaaf vertoon moet word" -#: gtk/gtkentry.c:1683 +#: gtk/gtkentry.c:1714 msgid "Border between text and frame." msgstr "" -#: gtk/gtkentry.c:1697 +#: gtk/gtkentry.c:1728 #, fuzzy msgid "State Hint" msgstr "Reëlsverwenking" -#: gtk/gtkentry.c:1698 +#: gtk/gtkentry.c:1729 #, fuzzy msgid "Whether to pass a proper state when drawing shadow or background" msgstr "Biskaart om as masker te gebruik wanneer teksagtergrond geteken word" -#: gtk/gtkentry.c:1703 gtk/gtklabel.c:830 +#: gtk/gtkentry.c:1734 gtk/gtklabel.c:848 msgid "Select on focus" msgstr "Merk by fokus" -#: gtk/gtkentry.c:1704 +#: gtk/gtkentry.c:1735 msgid "Whether to select the contents of an entry when it is focused" msgstr "" "Of die inhoud van 'n inskrywing gemerk moet word wanneer die fokus daarop is" -#: gtk/gtkentry.c:1718 +#: gtk/gtkentry.c:1749 msgid "Password Hint Timeout" msgstr "" -#: gtk/gtkentry.c:1719 +#: gtk/gtkentry.c:1750 msgid "How long to show the last input character in hidden entries" msgstr "" +#: gtk/gtkentrybuffer.c:354 +#, fuzzy +msgid "The contents of the buffer" +msgstr "Die inhoud van die inskrywing" + +#: gtk/gtkentrybuffer.c:369 +msgid "Length of the text currently in the buffer" +msgstr "" + #: gtk/gtkentrycompletion.c:279 msgid "Completion Model" msgstr "Voltooiingsmodel" @@ -2618,7 +2670,7 @@ msgstr "minimum knoppielengte" msgid "Minimum length of the search key in order to look up matches" msgstr "minimum lengte van die soekknoppie nodig om vir pare te soek" -#: gtk/gtkentrycompletion.c:303 gtk/gtkiconview.c:585 +#: gtk/gtkentrycompletion.c:303 gtk/gtkiconview.c:586 #, fuzzy msgid "Text column" msgstr "Tekskolom" @@ -2709,11 +2761,11 @@ msgstr "Of die uitvouer oopgemaak is om die kinddingesie te vertoon" msgid "Text of the expander's label" msgstr "Teks op die uitvouer se etiket" -#: gtk/gtkexpander.c:211 gtk/gtklabel.c:509 +#: gtk/gtkexpander.c:211 gtk/gtklabel.c:510 msgid "Use markup" msgstr "Gebruik markering" -#: gtk/gtkexpander.c:212 gtk/gtklabel.c:510 +#: gtk/gtkexpander.c:212 gtk/gtklabel.c:511 msgid "The text of the label includes XML markup. See pango_parse_markup()" msgstr "" "Die teks van die etiket sluit XML-markering in. Kyk pango_parse_markup()" @@ -2731,11 +2783,11 @@ msgid "A widget to display in place of the usual expander label" msgstr "" "'n Dingesie wat in die plek van die gewone uitvoueretiket vertoon moet word" -#: gtk/gtkexpander.c:236 gtk/gtktreeview.c:783 +#: gtk/gtkexpander.c:236 gtk/gtktreeview.c:774 msgid "Expander Size" msgstr "Uitvouergrootte" -#: gtk/gtkexpander.c:237 gtk/gtktreeview.c:784 +#: gtk/gtkexpander.c:237 gtk/gtktreeview.c:775 msgid "Size of the expander arrow" msgstr "Grootte van die uitvouerpyltjie" @@ -2838,6 +2890,17 @@ msgid "" "dialog if necessary." msgstr "" +#: gtk/gtkfilechooser.c:283 +#, fuzzy +msgid "Allow folders creation" +msgstr "Vertoon lêeroperasies" + +#: gtk/gtkfilechooser.c:284 +msgid "" +"Whether a file chooser not in open mode will offer the user to create new " +"folders." +msgstr "" + #: gtk/gtkfilechooserbutton.c:376 msgid "Dialog" msgstr "" @@ -2856,7 +2919,7 @@ msgid "The desired width of the button widget, in characters." msgstr "" #: gtk/gtkfilesel.c:526 gtk/gtkimage.c:163 gtk/gtkrecentmanager.c:214 -#: gtk/gtkstatusicon.c:218 +#: gtk/gtkstatusicon.c:221 msgid "Filename" msgstr "Lêernaam" @@ -3035,95 +3098,95 @@ msgid "" "detached." msgstr "" -#: gtk/gtkiconview.c:548 +#: gtk/gtkiconview.c:549 #, fuzzy msgid "Selection mode" msgstr "Seleksiegrens" -#: gtk/gtkiconview.c:549 +#: gtk/gtkiconview.c:550 #, fuzzy msgid "The selection mode" msgstr "Die geselekteerde jaar" -#: gtk/gtkiconview.c:567 +#: gtk/gtkiconview.c:568 #, fuzzy msgid "Pixbuf column" msgstr "Tekskolom" -#: gtk/gtkiconview.c:568 +#: gtk/gtkiconview.c:569 msgid "Model column used to retrieve the icon pixbuf from" msgstr "" -#: gtk/gtkiconview.c:586 +#: gtk/gtkiconview.c:587 msgid "Model column used to retrieve the text from" msgstr "" -#: gtk/gtkiconview.c:605 +#: gtk/gtkiconview.c:606 #, fuzzy msgid "Markup column" msgstr "Markering" -#: gtk/gtkiconview.c:606 +#: gtk/gtkiconview.c:607 msgid "Model column used to retrieve the text if using Pango markup" msgstr "" -#: gtk/gtkiconview.c:613 +#: gtk/gtkiconview.c:614 #, fuzzy msgid "Icon View Model" msgstr "TreeView-model" -#: gtk/gtkiconview.c:614 +#: gtk/gtkiconview.c:615 #, fuzzy msgid "The model for the icon view" msgstr "Die model vir die boomaansig" -#: gtk/gtkiconview.c:630 +#: gtk/gtkiconview.c:631 #, fuzzy msgid "Number of columns" msgstr "Getal kanale" -#: gtk/gtkiconview.c:631 +#: gtk/gtkiconview.c:632 #, fuzzy msgid "Number of columns to display" msgstr "Die getal desimale plekke om te vertoon" -#: gtk/gtkiconview.c:648 +#: gtk/gtkiconview.c:649 #, fuzzy msgid "Width for each item" msgstr "Dingesie wat as die itemetiket gebruik moet word" -#: gtk/gtkiconview.c:649 +#: gtk/gtkiconview.c:650 msgid "The width used for each item" msgstr "" -#: gtk/gtkiconview.c:665 +#: gtk/gtkiconview.c:666 msgid "Space which is inserted between cells of an item" msgstr "" -#: gtk/gtkiconview.c:680 +#: gtk/gtkiconview.c:681 #, fuzzy msgid "Row Spacing" msgstr "Ryspasiëring" -#: gtk/gtkiconview.c:681 +#: gtk/gtkiconview.c:682 msgid "Space which is inserted between grid rows" msgstr "" -#: gtk/gtkiconview.c:696 +#: gtk/gtkiconview.c:697 #, fuzzy msgid "Column Spacing" msgstr "Kolomspasiëring" -#: gtk/gtkiconview.c:697 +#: gtk/gtkiconview.c:698 msgid "Space which is inserted between grid columns" msgstr "" -#: gtk/gtkiconview.c:712 +#: gtk/gtkiconview.c:713 #, fuzzy msgid "Margin" msgstr "Linkergrens" -#: gtk/gtkiconview.c:713 +#: gtk/gtkiconview.c:714 msgid "Space which is inserted at the edges of the icon view" msgstr "" @@ -3132,15 +3195,15 @@ msgid "" "How the text and icon of each item are positioned relative to each other" msgstr "" -#: gtk/gtkiconview.c:746 gtk/gtktreeview.c:618 gtk/gtktreeviewcolumn.c:307 +#: gtk/gtkiconview.c:746 gtk/gtktreeview.c:609 gtk/gtktreeviewcolumn.c:308 msgid "Reorderable" msgstr "Hersorteerbaar" -#: gtk/gtkiconview.c:747 gtk/gtktreeview.c:619 +#: gtk/gtkiconview.c:747 gtk/gtktreeview.c:610 msgid "View is reorderable" msgstr "Aansig is hersorteerbaar" -#: gtk/gtkiconview.c:754 gtk/gtktreeview.c:769 +#: gtk/gtkiconview.c:754 gtk/gtktreeview.c:760 #, fuzzy msgid "Tooltip Column" msgstr "Tekskolom" @@ -3150,31 +3213,40 @@ msgstr "Tekskolom" msgid "The column in the model containing the tooltip texts for the items" msgstr "'n Kolom in die databronmodel waaruit die stringe verkry moet word" -#: gtk/gtkiconview.c:766 +#: gtk/gtkiconview.c:772 +#, fuzzy +msgid "Item Padding" +msgstr "Onderkantopvulling" + +#: gtk/gtkiconview.c:773 +msgid "Padding around icon view items" +msgstr "" + +#: gtk/gtkiconview.c:782 #, fuzzy msgid "Selection Box Color" msgstr "Seleksiegrens" -#: gtk/gtkiconview.c:767 +#: gtk/gtkiconview.c:783 #, fuzzy msgid "Color of the selection box" msgstr "Die titel van die fontkies-dialoog" -#: gtk/gtkiconview.c:773 +#: gtk/gtkiconview.c:789 #, fuzzy msgid "Selection Box Alpha" msgstr "Seleksiegrens" -#: gtk/gtkiconview.c:774 +#: gtk/gtkiconview.c:790 #, fuzzy msgid "Opacity of the selection box" msgstr "Die titel van die fontkies-dialoog" -#: gtk/gtkimage.c:131 gtk/gtkstatusicon.c:210 +#: gtk/gtkimage.c:131 gtk/gtkstatusicon.c:213 msgid "Pixbuf" msgstr "Pixbuf" -#: gtk/gtkimage.c:132 gtk/gtkstatusicon.c:211 +#: gtk/gtkimage.c:132 gtk/gtkstatusicon.c:214 msgid "A GdkPixbuf to display" msgstr "'n GdkPixbuf om te vertoon" @@ -3202,11 +3274,11 @@ msgstr "Masker" msgid "Mask bitmap to use with GdkImage or GdkPixmap" msgstr "Maskerbismatriks om met GdkImage of GdkPixmap te gebruik" -#: gtk/gtkimage.c:164 gtk/gtkstatusicon.c:219 +#: gtk/gtkimage.c:164 gtk/gtkstatusicon.c:222 msgid "Filename to load and display" msgstr "Lêernaam wat gelaai en vertoon moet word" -#: gtk/gtkimage.c:173 gtk/gtkstatusicon.c:227 +#: gtk/gtkimage.c:173 gtk/gtkstatusicon.c:230 msgid "Stock ID for a stock image to display" msgstr "Stapel-ID vir 'n stapelbeeld wat vertoon moet word" @@ -3245,11 +3317,11 @@ msgstr "Animasie" msgid "GdkPixbufAnimation to display" msgstr "GdkPixbufAnimation om te vertoon" -#: gtk/gtkimage.c:255 gtk/gtkstatusicon.c:258 +#: gtk/gtkimage.c:255 gtk/gtkstatusicon.c:261 msgid "Storage type" msgstr "Bergsoort" -#: gtk/gtkimage.c:256 gtk/gtkstatusicon.c:259 +#: gtk/gtkimage.c:256 gtk/gtkstatusicon.c:262 msgid "The representation being used for image data" msgstr "Die voorstelling wat vir die beelddata gebruik word" @@ -3271,7 +3343,7 @@ msgstr "" msgid "Whether the image will always be shown" msgstr "Of die dingesie sigbaar is" -#: gtk/gtkimagemenuitem.c:184 gtk/gtkmenu.c:515 +#: gtk/gtkimagemenuitem.c:184 gtk/gtkmenu.c:516 #, fuzzy msgid "Accel Group" msgstr "Aksiegroep" @@ -3289,23 +3361,46 @@ msgstr "Vertoon kieslysbeelde" msgid "Whether images should be shown in menus" msgstr "Of beelde in kieslyste vertoon moet word" +#: gtk/gtkinfobar.c:384 gtk/gtkmessagedialog.c:128 +msgid "Message Type" +msgstr "Boodskapsoort" + +#: gtk/gtkinfobar.c:385 gtk/gtkmessagedialog.c:129 +msgid "The type of message" +msgstr "Die soort boodskap" + +#: gtk/gtkinfobar.c:440 +#, fuzzy +msgid "Width of border around the content area" +msgstr "Wydte van grens rondom die hoofdialoogstreek" + +#: gtk/gtkinfobar.c:457 +#, fuzzy +msgid "Spacing between elements of the area" +msgstr "Ruimte tussen waardeteks en die skuifknoppie/trog-streek" + +#: gtk/gtkinfobar.c:489 +#, fuzzy +msgid "Width of border around the action area" +msgstr "Wydte van grens rondom die hoofdialoogstreek" + #: gtk/gtkinvisible.c:87 gtk/gtkwindow.c:615 msgid "The screen where this window will be displayed" msgstr "Die skerm waarop hierdie venster vertoon sal word" -#: gtk/gtklabel.c:496 +#: gtk/gtklabel.c:497 msgid "The text of the label" msgstr "Die teks van die etiket" -#: gtk/gtklabel.c:503 +#: gtk/gtklabel.c:504 msgid "A list of style attributes to apply to the text of the label" msgstr "'n Lys stylattribute om op die teks van die etiket toe te pas" -#: gtk/gtklabel.c:524 gtk/gtktexttag.c:359 gtk/gtktextview.c:590 +#: gtk/gtklabel.c:525 gtk/gtktexttag.c:359 gtk/gtktextview.c:591 msgid "Justification" msgstr "Alkantbelyning" -#: gtk/gtklabel.c:525 +#: gtk/gtklabel.c:526 msgid "" "The alignment of the lines in the text of the label relative to each other. " "This does NOT affect the alignment of the label within its allocation. See " @@ -3315,11 +3410,11 @@ msgstr "" "mekaar. \vDit het NIE 'n uitwerking op die belyning van die etiket binne sy " "allokasie nie. Kyk GtkMisc::xalign daarvoor" -#: gtk/gtklabel.c:533 +#: gtk/gtklabel.c:534 msgid "Pattern" msgstr "Patroon" -#: gtk/gtklabel.c:534 +#: gtk/gtklabel.c:535 msgid "" "A string with _ characters in positions correspond to characters in the text " "to underline" @@ -3327,83 +3422,93 @@ msgstr "" "'n String met _ karakters in posisies wat ooreenstem met karakters in die " "teks wat onderstreep moet word" -#: gtk/gtklabel.c:541 +#: gtk/gtklabel.c:542 msgid "Line wrap" msgstr "Reëlvou" -#: gtk/gtklabel.c:542 +#: gtk/gtklabel.c:543 msgid "If set, wrap lines if the text becomes too wide" msgstr "Indien gestel word reëls gevou indien die teks te breed word" -#: gtk/gtklabel.c:557 +#: gtk/gtklabel.c:558 #, fuzzy msgid "Line wrap mode" msgstr "Reëlvou" -#: gtk/gtklabel.c:558 +#: gtk/gtklabel.c:559 msgid "If wrap is set, controls how linewrapping is done" msgstr "" -#: gtk/gtklabel.c:565 +#: gtk/gtklabel.c:566 msgid "Selectable" msgstr "Kiesbaar" -#: gtk/gtklabel.c:566 +#: gtk/gtklabel.c:567 msgid "Whether the label text can be selected with the mouse" msgstr "Of die etiketteks met die muis gekies kan word" -#: gtk/gtklabel.c:572 +#: gtk/gtklabel.c:573 msgid "Mnemonic key" msgstr "Mnemoniese sleutel" -#: gtk/gtklabel.c:573 +#: gtk/gtklabel.c:574 msgid "The mnemonic accelerator key for this label" msgstr "Die mnemoniese snelsleutel vir hierdie etiket" -#: gtk/gtklabel.c:581 +#: gtk/gtklabel.c:582 msgid "Mnemonic widget" msgstr "Mnemoniese dingesie" -#: gtk/gtklabel.c:582 +#: gtk/gtklabel.c:583 msgid "The widget to be activated when the label's mnemonic key is pressed" msgstr "" "Die dingesie wat geaktiveer moet word wanneer die etiket se mnemoniese " "sleutel gedruk word" -#: gtk/gtklabel.c:628 +#: gtk/gtklabel.c:629 msgid "" "The preferred place to ellipsize the string, if the label does not have " "enough room to display the entire string" msgstr "" -#: gtk/gtklabel.c:668 +#: gtk/gtklabel.c:669 #, fuzzy msgid "Single Line Mode" msgstr "Enkelparagraaf-modus" -#: gtk/gtklabel.c:669 +#: gtk/gtklabel.c:670 #, fuzzy msgid "Whether the label is in single line mode" msgstr "Of die etiket in die geselekteerde font geteken moet word" -#: gtk/gtklabel.c:686 +#: gtk/gtklabel.c:687 msgid "Angle" msgstr "" -#: gtk/gtklabel.c:687 +#: gtk/gtklabel.c:688 msgid "Angle at which the label is rotated" msgstr "" -#: gtk/gtklabel.c:707 +#: gtk/gtklabel.c:708 #, fuzzy msgid "Maximum Width In Characters" msgstr "Wydte in karakters" -#: gtk/gtklabel.c:708 +#: gtk/gtklabel.c:709 msgid "The desired maximum width of the label, in characters" msgstr "" -#: gtk/gtklabel.c:831 +#: gtk/gtklabel.c:727 +#, fuzzy +msgid "Track visited links" +msgstr "Die titel van die fontkies-dialoog" + +#: gtk/gtklabel.c:728 +#, fuzzy +msgid "Whether visited links should be tracked" +msgstr "Of die verskuilde lêers en gidse vertoon moet word" + +#: gtk/gtklabel.c:849 #, fuzzy msgid "Whether to select the contents of a selectable label when it is focused" msgstr "" @@ -3452,35 +3557,35 @@ msgstr "Sigbaar" msgid "Whether this link has been visited." msgstr "Of die aksie sigbaar is." -#: gtk/gtkmenu.c:501 +#: gtk/gtkmenu.c:502 #, fuzzy msgid "The currently selected menu item" msgstr "Die huidig geselekteerde lêernaam" -#: gtk/gtkmenu.c:516 +#: gtk/gtkmenu.c:517 #, fuzzy msgid "The accel group holding accelerators for the menu" msgstr "Die mnemoniese snelsleutel vir hierdie etiket" -#: gtk/gtkmenu.c:530 gtk/gtkmenuitem.c:285 +#: gtk/gtkmenu.c:531 gtk/gtkmenuitem.c:290 msgid "Accel Path" msgstr "" -#: gtk/gtkmenu.c:531 +#: gtk/gtkmenu.c:532 msgid "An accel path used to conveniently construct accel paths of child items" msgstr "" -#: gtk/gtkmenu.c:547 +#: gtk/gtkmenu.c:548 #, fuzzy msgid "Attach Widget" msgstr "Ekstra dingesie" -#: gtk/gtkmenu.c:548 +#: gtk/gtkmenu.c:549 #, fuzzy msgid "The widget the menu is attached to" msgstr "Of die kieslysitem gemerk is" -#: gtk/gtkmenu.c:556 +#: gtk/gtkmenu.c:557 msgid "" "A title that may be displayed by the window manager when this menu is torn-" "off" @@ -3488,50 +3593,63 @@ msgstr "" "'n Titel wat deur die vensterbestuurder vertoon kan word wanneer hierdie " "kieslys afgeskeur word" -#: gtk/gtkmenu.c:570 +#: gtk/gtkmenu.c:571 #, fuzzy msgid "Tearoff State" msgstr "Afskeurtitel" -#: gtk/gtkmenu.c:571 +#: gtk/gtkmenu.c:572 #, fuzzy msgid "A boolean that indicates whether the menu is torn-off" msgstr "" "'n Titel wat deur die vensterbestuurder vertoon kan word wanneer hierdie " "kieslys afgeskeur word" -#: gtk/gtkmenu.c:585 +#: gtk/gtkmenu.c:586 #, fuzzy msgid "Monitor" msgstr "Maand" -#: gtk/gtkmenu.c:586 +#: gtk/gtkmenu.c:587 msgid "The monitor the menu will be popped up on" msgstr "" -#: gtk/gtkmenu.c:592 +#: gtk/gtkmenu.c:593 msgid "Vertical Padding" msgstr "Vertikale opvulling" -#: gtk/gtkmenu.c:593 +#: gtk/gtkmenu.c:594 msgid "Extra space at the top and bottom of the menu" msgstr "Ekstra ruimte aan bo- en onderkant van die kieslys" -#: gtk/gtkmenu.c:601 +#: gtk/gtkmenu.c:616 +msgid "Reserve Toggle Size" +msgstr "" + +#: gtk/gtkmenu.c:617 +#, fuzzy +msgid "" +"A boolean that indicates whether the menu reserves space for toggles and " +"icons" +msgstr "" +"'n Titel wat deur die vensterbestuurder vertoon kan word wanneer hierdie " +"kieslys afgeskeur word" + +#: gtk/gtkmenu.c:623 #, fuzzy msgid "Horizontal Padding" msgstr "Horisontale opvulling" -#: gtk/gtkmenu.c:602 +#: gtk/gtkmenu.c:624 #, fuzzy msgid "Extra space at the left and right edges of the menu" msgstr "Ekstra ruimte aan bo- en onderkant van die kieslys" -#: gtk/gtkmenu.c:610 +#: gtk/gtkmenu.c:632 msgid "Vertical Offset" msgstr "Vertikale verplasing" -#: gtk/gtkmenu.c:611 +#: gtk/gtkmenu.c:633 msgid "" "When the menu is a submenu, position it this number of pixels offset " "vertically" @@ -3539,11 +3657,11 @@ msgstr "" "Wanneer die kieslys 'n subkieslys is, word dit hierdie getal pixels " "vertikaal verplaas" -#: gtk/gtkmenu.c:619 +#: gtk/gtkmenu.c:641 msgid "Horizontal Offset" msgstr "Horisontale verplasing" -#: gtk/gtkmenu.c:620 +#: gtk/gtkmenu.c:642 msgid "" "When the menu is a submenu, position it this number of pixels offset " "horizontally" @@ -3551,88 +3669,88 @@ msgstr "" "Wanneer die kieslys 'n subkieslys is, word dit hierdie getal pixels " "horisontaal verplaas" -#: gtk/gtkmenu.c:628 +#: gtk/gtkmenu.c:650 #, fuzzy msgid "Double Arrows" msgstr "Vertoon pyltjie" -#: gtk/gtkmenu.c:629 +#: gtk/gtkmenu.c:651 msgid "When scrolling, always show both arrows." msgstr "" -#: gtk/gtkmenu.c:642 +#: gtk/gtkmenu.c:664 #, fuzzy msgid "Arrow Placement" msgstr "Pyltjie-x-verplasing" -#: gtk/gtkmenu.c:643 +#: gtk/gtkmenu.c:665 msgid "Indicates where scroll arrows should be placed" msgstr "" -#: gtk/gtkmenu.c:651 +#: gtk/gtkmenu.c:673 msgid "Left Attach" msgstr "Linkeraanhegting" -#: gtk/gtkmenu.c:652 gtk/gtktable.c:174 +#: gtk/gtkmenu.c:674 gtk/gtktable.c:174 msgid "The column number to attach the left side of the child to" msgstr "Die kolomnommer waaraan die linkersy van die kind geheg moet word" -#: gtk/gtkmenu.c:659 +#: gtk/gtkmenu.c:681 msgid "Right Attach" msgstr "Regteraanhegting" -#: gtk/gtkmenu.c:660 +#: gtk/gtkmenu.c:682 msgid "The column number to attach the right side of the child to" msgstr "Die kolomnommer waaraan die regtersy van die kind geheg moet word" -#: gtk/gtkmenu.c:667 +#: gtk/gtkmenu.c:689 msgid "Top Attach" msgstr "Boaanhegting" -#: gtk/gtkmenu.c:668 +#: gtk/gtkmenu.c:690 msgid "The row number to attach the top of the child to" msgstr "Die kolomnommer waaraan die bokantste sy van die kind geheg moet word" -#: gtk/gtkmenu.c:675 +#: gtk/gtkmenu.c:697 msgid "Bottom Attach" msgstr "Onderaanhegting" -#: gtk/gtkmenu.c:676 gtk/gtktable.c:195 +#: gtk/gtkmenu.c:698 gtk/gtktable.c:195 msgid "The row number to attach the bottom of the child to" msgstr "" "Die kolomnommer waaraan die onderkantste sy van die kind geheg moet word" -#: gtk/gtkmenu.c:690 +#: gtk/gtkmenu.c:712 msgid "Arbitrary constant to scale down the size of the scroll arrow" msgstr "" -#: gtk/gtkmenu.c:777 +#: gtk/gtkmenu.c:799 msgid "Can change accelerators" msgstr "Kan snelsleutels wysig" -#: gtk/gtkmenu.c:778 +#: gtk/gtkmenu.c:800 msgid "" "Whether menu accelerators can be changed by pressing a key over the menu item" msgstr "" "Of kieslyssnelsleutels gewysig kan word deur 'n sleutel oor die kieslysitem " "te druk" -#: gtk/gtkmenu.c:783 +#: gtk/gtkmenu.c:805 msgid "Delay before submenus appear" msgstr "Vertraag voor subkieslyste verskyn" -#: gtk/gtkmenu.c:784 +#: gtk/gtkmenu.c:806 msgid "" "Minimum time the pointer must stay over a menu item before the submenu appear" msgstr "" "minimum tyd wat die wyser oor 'n kieslysitem moet wag voor die subkieslys " "verskyn" -#: gtk/gtkmenu.c:791 +#: gtk/gtkmenu.c:813 msgid "Delay before hiding a submenu" msgstr "Vertraging voor subkieslys verskuil word" -#: gtk/gtkmenu.c:792 +#: gtk/gtkmenu.c:814 msgid "" "The time before hiding a submenu when the pointer is moving towards the " "submenu" @@ -3680,42 +3798,42 @@ msgstr "Vertraging voor aftuimelkieslyste verskyn" msgid "Delay before the submenus of a menu bar appear" msgstr "Vertraging voor die subkieslyste van 'n kieslysstaaf verskyn" -#: gtk/gtkmenuitem.c:252 +#: gtk/gtkmenuitem.c:257 msgid "Right Justified" msgstr "" -#: gtk/gtkmenuitem.c:253 +#: gtk/gtkmenuitem.c:258 msgid "" "Sets whether the menu item appears justified at the right side of a menu bar" msgstr "" -#: gtk/gtkmenuitem.c:267 +#: gtk/gtkmenuitem.c:272 msgid "Submenu" msgstr "" -#: gtk/gtkmenuitem.c:268 +#: gtk/gtkmenuitem.c:273 msgid "The submenu attached to the menu item, or NULL if it has none" msgstr "" -#: gtk/gtkmenuitem.c:286 +#: gtk/gtkmenuitem.c:291 msgid "Sets the accelerator path of the menu item" msgstr "" -#: gtk/gtkmenuitem.c:301 +#: gtk/gtkmenuitem.c:306 #, fuzzy msgid "The text for the child label" msgstr "Die teks van die etiket" -#: gtk/gtkmenuitem.c:364 +#: gtk/gtkmenuitem.c:369 msgid "Amount of space used up by arrow, relative to the menu item's font size" msgstr "" -#: gtk/gtkmenuitem.c:377 +#: gtk/gtkmenuitem.c:382 #, fuzzy msgid "Width in Characters" msgstr "Wydte in karakters" -#: gtk/gtkmenuitem.c:378 +#: gtk/gtkmenuitem.c:383 msgid "The minimum desired width of the menu item in characters" msgstr "" @@ -3758,14 +3876,6 @@ msgstr "" "Of 'n skeier tussen die boodskap se dialoogteks en die knoppies geplaas moet " "word" -#: gtk/gtkmessagedialog.c:128 -msgid "Message Type" -msgstr "Boodskapsoort" - -#: gtk/gtkmessagedialog.c:129 -msgid "The type of message" -msgstr "Die soort boodskap" - #: gtk/gtkmessagedialog.c:136 msgid "Message Buttons" msgstr "Boodskapknoppies" @@ -3843,26 +3953,26 @@ msgstr "" "Die hoeveelheid ruimte wat bo en onder die dingesie gevoeg moet word, in " "pixels" -#: gtk/gtkmountoperation.c:139 +#: gtk/gtkmountoperation.c:160 #, fuzzy msgid "Parent" msgstr "Ouerdingesie" -#: gtk/gtkmountoperation.c:140 +#: gtk/gtkmountoperation.c:161 #, fuzzy msgid "The parent window" msgstr "Die soort venster" -#: gtk/gtkmountoperation.c:147 +#: gtk/gtkmountoperation.c:168 #, fuzzy msgid "Is Showing" msgstr "Toon kop" -#: gtk/gtkmountoperation.c:148 +#: gtk/gtkmountoperation.c:169 msgid "Are we showing a dialog" msgstr "" -#: gtk/gtkmountoperation.c:156 +#: gtk/gtkmountoperation.c:177 #, fuzzy msgid "The screen where this window will be displayed." msgstr "Die skerm waarop hierdie venster vertoon sal word" @@ -4174,7 +4284,7 @@ msgstr "Verklein" msgid "If TRUE, the child can be made smaller than its requisition" msgstr "Indien WAAR kan die kind kleiner gemaak word as rekwisisie" -#: gtk/gtkplug.c:150 gtk/gtkstatusicon.c:309 +#: gtk/gtkplug.c:150 gtk/gtkstatusicon.c:312 msgid "Embedded" msgstr "" @@ -4321,12 +4431,12 @@ msgstr "" msgid "Printer settings" msgstr "" -#: gtk/gtkprintjob.c:143 gtk/gtkprintjob.c:144 gtk/gtkprintunixdialog.c:266 +#: gtk/gtkprintjob.c:143 gtk/gtkprintjob.c:144 gtk/gtkprintunixdialog.c:302 #, fuzzy msgid "Page Setup" msgstr "Bladsygrootte" -#: gtk/gtkprintjob.c:152 gtk/gtkprintoperation.c:1056 +#: gtk/gtkprintjob.c:152 gtk/gtkprintoperation.c:1082 msgid "Track Print Status" msgstr "" @@ -4336,176 +4446,199 @@ msgid "" "print data has been sent to the printer or print server." msgstr "" -#: gtk/gtkprintoperation.c:928 +#: gtk/gtkprintoperation.c:954 #, fuzzy msgid "Default Page Setup" msgstr "Verstekhoogte" -#: gtk/gtkprintoperation.c:929 +#: gtk/gtkprintoperation.c:955 msgid "The GtkPageSetup used by default" msgstr "" -#: gtk/gtkprintoperation.c:947 gtk/gtkprintunixdialog.c:284 +#: gtk/gtkprintoperation.c:973 gtk/gtkprintunixdialog.c:320 msgid "Print Settings" msgstr "" -#: gtk/gtkprintoperation.c:948 gtk/gtkprintunixdialog.c:285 +#: gtk/gtkprintoperation.c:974 gtk/gtkprintunixdialog.c:321 msgid "The GtkPrintSettings used for initializing the dialog" msgstr "" -#: gtk/gtkprintoperation.c:966 +#: gtk/gtkprintoperation.c:992 #, fuzzy msgid "Job Name" msgstr "Fontnaam" -#: gtk/gtkprintoperation.c:967 +#: gtk/gtkprintoperation.c:993 msgid "A string used for identifying the print job." msgstr "" -#: gtk/gtkprintoperation.c:991 +#: gtk/gtkprintoperation.c:1017 #, fuzzy msgid "Number of Pages" msgstr "Getal kanale" -#: gtk/gtkprintoperation.c:992 +#: gtk/gtkprintoperation.c:1018 #, fuzzy msgid "The number of pages in the document." msgstr "Die getal rye in die tabel" -#: gtk/gtkprintoperation.c:1013 gtk/gtkprintunixdialog.c:274 +#: gtk/gtkprintoperation.c:1039 gtk/gtkprintunixdialog.c:310 #, fuzzy msgid "Current Page" msgstr "Huidige alfa" -#: gtk/gtkprintoperation.c:1014 gtk/gtkprintunixdialog.c:275 +#: gtk/gtkprintoperation.c:1040 gtk/gtkprintunixdialog.c:311 #, fuzzy msgid "The current page in the document" msgstr "Die bladsygrootte van die aanpassing" -#: gtk/gtkprintoperation.c:1035 +#: gtk/gtkprintoperation.c:1061 #, fuzzy msgid "Use full page" msgstr "Gebruik alfa" -#: gtk/gtkprintoperation.c:1036 +#: gtk/gtkprintoperation.c:1062 msgid "" "TRUE if the origin of the context should be at the corner of the page and " "not the corner of the imageable area" msgstr "" -#: gtk/gtkprintoperation.c:1057 +#: gtk/gtkprintoperation.c:1083 msgid "" "TRUE if the print operation will continue to report on the print job status " "after the print data has been sent to the printer or print server." msgstr "" -#: gtk/gtkprintoperation.c:1074 +#: gtk/gtkprintoperation.c:1100 msgid "Unit" msgstr "" -#: gtk/gtkprintoperation.c:1075 +#: gtk/gtkprintoperation.c:1101 msgid "The unit in which distances can be measured in the context" msgstr "" -#: gtk/gtkprintoperation.c:1092 +#: gtk/gtkprintoperation.c:1118 #, fuzzy msgid "Show Dialog" msgstr "Toon kop" -#: gtk/gtkprintoperation.c:1093 +#: gtk/gtkprintoperation.c:1119 msgid "TRUE if a progress dialog is shown while printing." msgstr "" -#: gtk/gtkprintoperation.c:1116 +#: gtk/gtkprintoperation.c:1142 #, fuzzy msgid "Allow Async" msgstr "Laat reëls toe" -#: gtk/gtkprintoperation.c:1117 +#: gtk/gtkprintoperation.c:1143 msgid "TRUE if print process may run asynchronous." msgstr "" -#: gtk/gtkprintoperation.c:1139 gtk/gtkprintoperation.c:1140 +#: gtk/gtkprintoperation.c:1165 gtk/gtkprintoperation.c:1166 #, fuzzy msgid "Export filename" msgstr "Lêernaam" -#: gtk/gtkprintoperation.c:1154 +#: gtk/gtkprintoperation.c:1180 msgid "Status" msgstr "" -#: gtk/gtkprintoperation.c:1155 +#: gtk/gtkprintoperation.c:1181 #, fuzzy msgid "The status of the print operation" msgstr "Die swikstaat van die knoppie" -#: gtk/gtkprintoperation.c:1175 +#: gtk/gtkprintoperation.c:1201 msgid "Status String" msgstr "" -#: gtk/gtkprintoperation.c:1176 +#: gtk/gtkprintoperation.c:1202 msgid "A human-readable description of the status" msgstr "" -#: gtk/gtkprintoperation.c:1194 +#: gtk/gtkprintoperation.c:1220 #, fuzzy msgid "Custom tab label" msgstr "Doelgemaakte palet" -#: gtk/gtkprintoperation.c:1195 +#: gtk/gtkprintoperation.c:1221 msgid "Label for the tab containing custom widgets." msgstr "" -#: gtk/gtkprintoperation.c:1210 gtk/gtkprintunixdialog.c:309 +#: gtk/gtkprintoperation.c:1236 gtk/gtkprintunixdialog.c:345 #, fuzzy msgid "Support Selection" msgstr "Die titel van die fontkies-dialoog" -#: gtk/gtkprintoperation.c:1211 +#: gtk/gtkprintoperation.c:1237 msgid "TRUE if the print operation will support print of selection." msgstr "" -#: gtk/gtkprintoperation.c:1227 gtk/gtkprintunixdialog.c:317 +#: gtk/gtkprintoperation.c:1253 gtk/gtkprintunixdialog.c:353 #, fuzzy msgid "Has Selection" msgstr "Die geselekteerde jaar" -#: gtk/gtkprintoperation.c:1228 +#: gtk/gtkprintoperation.c:1254 msgid "TRUE if a selecion exists." msgstr "" -#: gtk/gtkprintunixdialog.c:267 +#: gtk/gtkprintoperation.c:1269 gtk/gtkprintunixdialog.c:361 +#, fuzzy +msgid "Embed Page Setup" +msgstr "Bladsygrootte" + +#: gtk/gtkprintoperation.c:1270 +msgid "TRUE if page setup combos are embedded in GtkPrintDialog" +msgstr "" + +#: gtk/gtkprintoperation.c:1291 +#, fuzzy +msgid "Number of Pages To Print" +msgstr "Getal kanale" + +#: gtk/gtkprintoperation.c:1292 +#, fuzzy +msgid "The number of pages that will be printed." +msgstr "Die getal rye in die tabel" + +#: gtk/gtkprintunixdialog.c:303 msgid "The GtkPageSetup to use" msgstr "" -#: gtk/gtkprintunixdialog.c:292 +#: gtk/gtkprintunixdialog.c:328 #, fuzzy msgid "Selected Printer" msgstr "Die geselekteerde jaar" -#: gtk/gtkprintunixdialog.c:293 +#: gtk/gtkprintunixdialog.c:329 #, fuzzy msgid "The GtkPrinter which is selected" msgstr "Die item wat tans aktief is" -#: gtk/gtkprintunixdialog.c:300 +#: gtk/gtkprintunixdialog.c:336 msgid "Manual Capabilites" msgstr "" -#: gtk/gtkprintunixdialog.c:301 +#: gtk/gtkprintunixdialog.c:337 msgid "Capabilities the application can handle" msgstr "" -#: gtk/gtkprintunixdialog.c:310 +#: gtk/gtkprintunixdialog.c:346 #, fuzzy msgid "Whether the dialog supports selection" msgstr "Of die etiket in die geselekteerde font geteken moet word" -#: gtk/gtkprintunixdialog.c:318 +#: gtk/gtkprintunixdialog.c:354 #, fuzzy msgid "Whether the application has a selection" msgstr "Of die aksie in werking gestel is." +#: gtk/gtkprintunixdialog.c:362 +msgid "TRUE if page setup combos are embedded in GtkPrintUnixDialog" +msgstr "" + #: gtk/gtkprogress.c:102 msgid "Activity mode" msgstr "Aktiwiteitsmodus" @@ -5105,11 +5238,11 @@ msgstr "" "Vertoon 'n tweede vorentoe-pyltjie op die teenoorgestelde punt van die " "rolstaaf" -#: gtk/gtkscrolledwindow.c:218 gtk/gtktext.c:545 gtk/gtktreeview.c:578 +#: gtk/gtkscrolledwindow.c:218 gtk/gtktext.c:545 gtk/gtktreeview.c:569 msgid "Horizontal Adjustment" msgstr "Horisontale verstelling" -#: gtk/gtkscrolledwindow.c:225 gtk/gtktext.c:553 gtk/gtktreeview.c:586 +#: gtk/gtkscrolledwindow.c:225 gtk/gtktext.c:553 gtk/gtktreeview.c:577 msgid "Vertical Adjustment" msgstr "Vertikale verstelling" @@ -5676,11 +5809,11 @@ msgstr "Nutswenk" msgid "Whether tooltips should be shown on widgets" msgstr "Of oortjies vertoon moet word of nie" -#: gtk/gtksizegroup.c:293 +#: gtk/gtksizegroup.c:301 msgid "Mode" msgstr "Modus" -#: gtk/gtksizegroup.c:294 +#: gtk/gtksizegroup.c:302 #, fuzzy msgid "" "The directions in which the size group affects the requested sizes of its " @@ -5689,11 +5822,11 @@ msgstr "" "Die rigtings waarin die grootte van die groep 'n uitwerking op die gevraagde " "groottes van sy komponentdingesies het" -#: gtk/gtksizegroup.c:310 +#: gtk/gtksizegroup.c:318 msgid "Ignore hidden" msgstr "" -#: gtk/gtksizegroup.c:311 +#: gtk/gtksizegroup.c:319 msgid "" "If TRUE, unmapped widgets are ignored when determining the size of the group" msgstr "" @@ -5765,70 +5898,75 @@ msgstr "Of die statusstaaf 'n greep bevat om die bokant te herskaleer" msgid "Style of bevel around the statusbar text" msgstr "Styl van skuinskant rondom die statusstaafteks" -#: gtk/gtkstatusicon.c:268 +#: gtk/gtkstatusicon.c:271 #, fuzzy msgid "The size of the icon" msgstr "Die titel van die venster" -#: gtk/gtkstatusicon.c:278 +#: gtk/gtkstatusicon.c:281 #, fuzzy msgid "The screen where this status icon will be displayed" msgstr "Die skerm waarop hierdie venster vertoon sal word" -#: gtk/gtkstatusicon.c:285 +#: gtk/gtkstatusicon.c:288 msgid "Blinking" msgstr "" -#: gtk/gtkstatusicon.c:286 +#: gtk/gtkstatusicon.c:289 #, fuzzy msgid "Whether or not the status icon is blinking" msgstr "Of die aksie sigbaar is." -#: gtk/gtkstatusicon.c:294 +#: gtk/gtkstatusicon.c:297 #, fuzzy msgid "Whether or not the status icon is visible" msgstr "Of die aksie sigbaar is." -#: gtk/gtkstatusicon.c:310 +#: gtk/gtkstatusicon.c:313 #, fuzzy msgid "Whether or not the status icon is embedded" msgstr "Of die aksie sigbaar is." -#: gtk/gtkstatusicon.c:326 gtk/gtktrayicon-x11.c:111 +#: gtk/gtkstatusicon.c:329 gtk/gtktrayicon-x11.c:111 #, fuzzy msgid "The orientation of the tray" msgstr "Die oriëntering van die nutsbalk" -#: gtk/gtkstatusicon.c:353 gtk/gtkwidget.c:632 +#: gtk/gtkstatusicon.c:356 gtk/gtkwidget.c:634 #, fuzzy msgid "Has tooltip" msgstr "Nutswenk" -#: gtk/gtkstatusicon.c:354 +#: gtk/gtkstatusicon.c:357 #, fuzzy msgid "Whether this tray icon has a tooltip" msgstr "Of die dingesie die toevoerfokus het" -#: gtk/gtkstatusicon.c:375 gtk/gtkwidget.c:653 +#: gtk/gtkstatusicon.c:382 gtk/gtkwidget.c:655 #, fuzzy msgid "Tooltip Text" msgstr "Nutswenk" -#: gtk/gtkstatusicon.c:376 gtk/gtkwidget.c:654 gtk/gtkwidget.c:675 +#: gtk/gtkstatusicon.c:383 gtk/gtkwidget.c:656 gtk/gtkwidget.c:677 #, fuzzy msgid "The contents of the tooltip for this widget" msgstr "Die inhoud van die inskrywing" -#: gtk/gtkstatusicon.c:399 gtk/gtkwidget.c:674 +#: gtk/gtkstatusicon.c:406 gtk/gtkwidget.c:676 #, fuzzy msgid "Tooltip markup" msgstr "Nutswenk" -#: gtk/gtkstatusicon.c:400 +#: gtk/gtkstatusicon.c:407 #, fuzzy msgid "The contents of the tooltip for this tray icon" msgstr "Die inhoud van die inskrywing" +#: gtk/gtkstatusicon.c:425 +#, fuzzy +msgid "The title of this tray icon" +msgstr "Die titel van die venster" + #: gtk/gtktable.c:129 msgid "Rows" msgstr "Rye" @@ -6110,7 +6248,7 @@ msgstr "" "eienskap pas behoorlik by temaveranderinge aan, en word dus aanbeveel. Pango " "stel sommige skale vooraf vas, soos PANGO_SCALE_X_LARGE" -#: gtk/gtktexttag.c:360 gtk/gtktextview.c:591 +#: gtk/gtktexttag.c:360 gtk/gtktextview.c:592 msgid "Left, right, or center justification" msgstr "Links-, regs- of middelbelyning" @@ -6128,7 +6266,7 @@ msgstr "" msgid "Left margin" msgstr "Linkergrens" -#: gtk/gtktexttag.c:387 gtk/gtktextview.c:600 +#: gtk/gtktexttag.c:387 gtk/gtktextview.c:601 msgid "Width of the left margin in pixels" msgstr "Wydte van die linkergrens in pixels" @@ -6136,15 +6274,15 @@ msgstr "Wydte van die linkergrens in pixels" msgid "Right margin" msgstr "Regtergrens" -#: gtk/gtktexttag.c:397 gtk/gtktextview.c:610 +#: gtk/gtktexttag.c:397 gtk/gtktextview.c:611 msgid "Width of the right margin in pixels" msgstr "Wydte van die regtergrens in pixels" -#: gtk/gtktexttag.c:407 gtk/gtktextview.c:619 +#: gtk/gtktexttag.c:407 gtk/gtktextview.c:620 msgid "Indent" msgstr "Keep" -#: gtk/gtktexttag.c:408 gtk/gtktextview.c:620 +#: gtk/gtktexttag.c:408 gtk/gtktextview.c:621 msgid "Amount to indent the paragraph, in pixels" msgstr "Hoeveel die paragraaf ingekeep moet word, in pixels" @@ -6161,7 +6299,7 @@ msgstr "" msgid "Pixels above lines" msgstr "Pixels bo reëls" -#: gtk/gtktexttag.c:429 gtk/gtktextview.c:544 +#: gtk/gtktexttag.c:429 gtk/gtktextview.c:545 msgid "Pixels of blank space above paragraphs" msgstr "Pixels leë spasie bokant paragrawe" @@ -6169,7 +6307,7 @@ msgstr "Pixels leë spasie bokant paragrawe" msgid "Pixels below lines" msgstr "Pixels onder reëls" -#: gtk/gtktexttag.c:439 gtk/gtktextview.c:554 +#: gtk/gtktexttag.c:439 gtk/gtktextview.c:555 msgid "Pixels of blank space below paragraphs" msgstr "Pixels leë spasie onder paragrawe" @@ -6177,22 +6315,22 @@ msgstr "Pixels leë spasie onder paragrawe" msgid "Pixels inside wrap" msgstr "Pixels binne omvou" -#: gtk/gtktexttag.c:449 gtk/gtktextview.c:564 +#: gtk/gtktexttag.c:449 gtk/gtktextview.c:565 msgid "Pixels of blank space between wrapped lines in a paragraph" msgstr "Pixels leë spasie tussen omgevoude reëls in 'n paragraaf" -#: gtk/gtktexttag.c:476 gtk/gtktextview.c:582 +#: gtk/gtktexttag.c:476 gtk/gtktextview.c:583 msgid "" "Whether to wrap lines never, at word boundaries, or at character boundaries" msgstr "" "Of reëls nooit nie, volgens woordgrens of volgens karaktergrens omgevou moet " "word" -#: gtk/gtktexttag.c:485 gtk/gtktextview.c:629 +#: gtk/gtktexttag.c:485 gtk/gtktextview.c:630 msgid "Tabs" msgstr "Kepe" -#: gtk/gtktexttag.c:486 gtk/gtktextview.c:630 +#: gtk/gtktexttag.c:486 gtk/gtktextview.c:631 msgid "Custom tabs for this text" msgstr "Doelmaak kepe vir hierdie teks" @@ -6345,64 +6483,64 @@ msgstr "Selagtergrondstel" msgid "Whether this tag affects the paragraph background color" msgstr "Of hierdie merker 'n uitwerking op die agtergrondkleur het" -#: gtk/gtktextview.c:543 +#: gtk/gtktextview.c:544 msgid "Pixels Above Lines" msgstr "Pixels bo reëls" -#: gtk/gtktextview.c:553 +#: gtk/gtktextview.c:554 msgid "Pixels Below Lines" msgstr "Pixels onder reëls" -#: gtk/gtktextview.c:563 +#: gtk/gtktextview.c:564 msgid "Pixels Inside Wrap" msgstr "Pixels binne omvou" -#: gtk/gtktextview.c:581 +#: gtk/gtktextview.c:582 msgid "Wrap Mode" msgstr "Omvou-modus" -#: gtk/gtktextview.c:599 +#: gtk/gtktextview.c:600 msgid "Left Margin" msgstr "Linkergrens" -#: gtk/gtktextview.c:609 +#: gtk/gtktextview.c:610 msgid "Right Margin" msgstr "Regtergrens" -#: gtk/gtktextview.c:637 +#: gtk/gtktextview.c:638 msgid "Cursor Visible" msgstr "Wyser sigbaar" -#: gtk/gtktextview.c:638 +#: gtk/gtktextview.c:639 msgid "If the insertion cursor is shown" msgstr "Of die invoegwyser vertoon word" -#: gtk/gtktextview.c:645 +#: gtk/gtktextview.c:646 msgid "Buffer" msgstr "Buffer" -#: gtk/gtktextview.c:646 +#: gtk/gtktextview.c:647 msgid "The buffer which is displayed" msgstr "Die buffer wat vertoon word" -#: gtk/gtktextview.c:654 +#: gtk/gtktextview.c:655 msgid "Whether entered text overwrites existing contents" msgstr "Of teks wat ingetik word, bestaande teks oorheenskryf" -#: gtk/gtktextview.c:661 +#: gtk/gtktextview.c:662 msgid "Accepts tab" msgstr "Aanvaar keep" -#: gtk/gtktextview.c:662 +#: gtk/gtktextview.c:663 msgid "Whether Tab will result in a tab character being entered" msgstr "Of Tab 'n keepkarakter sal intik" -#: gtk/gtktextview.c:691 +#: gtk/gtktextview.c:692 #, fuzzy msgid "Error underline color" msgstr "Voorgrondkleur" -#: gtk/gtktextview.c:692 +#: gtk/gtktextview.c:693 #, fuzzy msgid "Color with which to draw error-indication underlines" msgstr "Kleure waarmee die invoegwyser geteken moet word" @@ -6596,7 +6734,7 @@ msgstr "Ryspasiëring" msgid "Spacing in pixels between the icon and label" msgstr "Spasiëring tussen stapknoppies en duimpie" -#: gtk/gtktoolitem.c:191 +#: gtk/gtktoolitem.c:207 msgid "" "Whether the toolbar item is considered important. When TRUE, toolbar buttons " "show text in GTK_TOOLBAR_BOTH_HORIZ mode" @@ -6604,359 +6742,368 @@ msgstr "" "Of die nutsbalkitem as belangrik beskou word. Wanneer WAAR, wys " "nutsbalkknoppies teks vir hierdie aksie in GTK_TOOLBAR_BOTH_HORIZ-modus" -#: gtk/gtktreemodelsort.c:274 +#: gtk/gtktreemodelsort.c:278 msgid "TreeModelSort Model" msgstr "TreeModelSort-model" -#: gtk/gtktreemodelsort.c:275 +#: gtk/gtktreemodelsort.c:279 msgid "The model for the TreeModelSort to sort" msgstr "Die model vir die TreeModelSort om te sorteer" -#: gtk/gtktreeview.c:570 +#: gtk/gtktreeview.c:561 msgid "TreeView Model" msgstr "TreeView-model" -#: gtk/gtktreeview.c:571 +#: gtk/gtktreeview.c:562 msgid "The model for the tree view" msgstr "Die model vir die boomaansig" -#: gtk/gtktreeview.c:579 +#: gtk/gtktreeview.c:570 msgid "Horizontal Adjustment for the widget" msgstr "Horisontale verstelling vir die dingesie" -#: gtk/gtktreeview.c:587 +#: gtk/gtktreeview.c:578 msgid "Vertical Adjustment for the widget" msgstr "Vertikale verstelling vir die dingesie" -#: gtk/gtktreeview.c:594 +#: gtk/gtktreeview.c:585 #, fuzzy msgid "Headers Visible" msgstr "Koppe kliekbaar" -#: gtk/gtktreeview.c:595 +#: gtk/gtktreeview.c:586 msgid "Show the column header buttons" msgstr "Vertoon die kolomkopknoppies" -#: gtk/gtktreeview.c:602 +#: gtk/gtktreeview.c:593 msgid "Headers Clickable" msgstr "Koppe kliekbaar" -#: gtk/gtktreeview.c:603 +#: gtk/gtktreeview.c:594 msgid "Column headers respond to click events" msgstr "Kolomkoppe wat op kliekgebeure reageer" -#: gtk/gtktreeview.c:610 +#: gtk/gtktreeview.c:601 msgid "Expander Column" msgstr "Uitvouerkolom" -#: gtk/gtktreeview.c:611 +#: gtk/gtktreeview.c:602 msgid "Set the column for the expander column" msgstr "Stel die kolom vir die uitvouerkolom op" -#: gtk/gtktreeview.c:626 +#: gtk/gtktreeview.c:617 msgid "Rules Hint" msgstr "Reëlsverwenking" -#: gtk/gtktreeview.c:627 +#: gtk/gtktreeview.c:618 msgid "Set a hint to the theme engine to draw rows in alternating colors" msgstr "" "Stel 'n verwenking in die tema-enjin om rye in afwisselende kleure te teken" -#: gtk/gtktreeview.c:634 +#: gtk/gtktreeview.c:625 msgid "Enable Search" msgstr "Stel soektog in werking" -#: gtk/gtktreeview.c:635 +#: gtk/gtktreeview.c:626 msgid "View allows user to search through columns interactively" msgstr "Aansig stel gebruiker in staat om interaktief deur kolomme te soek" -#: gtk/gtktreeview.c:642 +#: gtk/gtktreeview.c:633 msgid "Search Column" msgstr "Deursoek kolom" -#: gtk/gtktreeview.c:643 +#: gtk/gtktreeview.c:634 #, fuzzy msgid "Model column to search through during interactive search" msgstr "Modelkolom waardeur gesoek moet word wanneer deur kode gesoek word" -#: gtk/gtktreeview.c:663 +#: gtk/gtktreeview.c:654 msgid "Fixed Height Mode" msgstr "Vastehoogte-modus" -#: gtk/gtktreeview.c:664 +#: gtk/gtktreeview.c:655 msgid "Speeds up GtkTreeView by assuming that all rows have the same height" msgstr "Versnel GtkTreeView deur te aanvaar dat alle rye dieselfde hoogte is" -#: gtk/gtktreeview.c:684 +#: gtk/gtktreeview.c:675 msgid "Hover Selection" msgstr "" -#: gtk/gtktreeview.c:685 +#: gtk/gtktreeview.c:676 #, fuzzy msgid "Whether the selection should follow the pointer" msgstr "" "Of die kleurkieser toegelaat moet word om die ondeursigtigheid te verstel" -#: gtk/gtktreeview.c:704 +#: gtk/gtktreeview.c:695 #, fuzzy msgid "Hover Expand" msgstr "Uitvou" -#: gtk/gtktreeview.c:705 +#: gtk/gtktreeview.c:696 #, fuzzy msgid "" "Whether rows should be expanded/collapsed when the pointer moves over them" msgstr "Of die venster deur die vensterbestuurder versier moet word" -#: gtk/gtktreeview.c:719 +#: gtk/gtktreeview.c:710 #, fuzzy msgid "Show Expanders" msgstr "Is uitvouer" -#: gtk/gtktreeview.c:720 +#: gtk/gtktreeview.c:711 #, fuzzy msgid "View has expanders" msgstr "Is uitvouer" -#: gtk/gtktreeview.c:734 +#: gtk/gtktreeview.c:725 msgid "Level Indentation" msgstr "" -#: gtk/gtktreeview.c:735 +#: gtk/gtktreeview.c:726 msgid "Extra indentation for each level" msgstr "" -#: gtk/gtktreeview.c:744 +#: gtk/gtktreeview.c:735 msgid "Rubber Banding" msgstr "" -#: gtk/gtktreeview.c:745 +#: gtk/gtktreeview.c:736 #, fuzzy msgid "" "Whether to enable selection of multiple items by dragging the mouse pointer" msgstr "Of meervoudige lêers geselekteer mag word" -#: gtk/gtktreeview.c:752 +#: gtk/gtktreeview.c:743 #, fuzzy msgid "Enable Grid Lines" msgstr "Stel pyltjiesleutels in werking" -#: gtk/gtktreeview.c:753 +#: gtk/gtktreeview.c:744 #, fuzzy msgid "Whether grid lines should be drawn in the tree view" msgstr "Of die grens vertoon moet word of nie" -#: gtk/gtktreeview.c:761 +#: gtk/gtktreeview.c:752 #, fuzzy msgid "Enable Tree Lines" msgstr "Stel pyltjiesleutels in werking" -#: gtk/gtktreeview.c:762 +#: gtk/gtktreeview.c:753 #, fuzzy msgid "Whether tree lines should be drawn in the tree view" msgstr "Of die grens vertoon moet word of nie" -#: gtk/gtktreeview.c:770 +#: gtk/gtktreeview.c:761 #, fuzzy msgid "The column in the model containing the tooltip texts for the rows" msgstr "'n Kolom in die databronmodel waaruit die stringe verkry moet word" -#: gtk/gtktreeview.c:792 +#: gtk/gtktreeview.c:783 msgid "Vertical Separator Width" msgstr "Vertikaleskeier-wydte" -#: gtk/gtktreeview.c:793 +#: gtk/gtktreeview.c:784 msgid "Vertical space between cells. Must be an even number" msgstr "Vertikale ruimte tussen selle. Moet 'n ewe getal wees" -#: gtk/gtktreeview.c:801 +#: gtk/gtktreeview.c:792 msgid "Horizontal Separator Width" msgstr "Horisontaleskeier-wydte" -#: gtk/gtktreeview.c:802 +#: gtk/gtktreeview.c:793 msgid "Horizontal space between cells. Must be an even number" msgstr "Vertikale ruimte tussen selle. Moet 'n ewe getal wees" -#: gtk/gtktreeview.c:810 +#: gtk/gtktreeview.c:801 msgid "Allow Rules" msgstr "Laat reëls toe" -#: gtk/gtktreeview.c:811 +#: gtk/gtktreeview.c:802 msgid "Allow drawing of alternating color rows" msgstr "Laat teken van afwisselende kleure rye toe" -#: gtk/gtktreeview.c:817 +#: gtk/gtktreeview.c:808 msgid "Indent Expanders" msgstr "Inkeepuitvouers" -#: gtk/gtktreeview.c:818 +#: gtk/gtktreeview.c:809 msgid "Make the expanders indented" msgstr "Maak die uitvouers ingekeep" -#: gtk/gtktreeview.c:824 +#: gtk/gtktreeview.c:815 msgid "Even Row Color" msgstr "Ewegetal-ry se kleur" -#: gtk/gtktreeview.c:825 +#: gtk/gtktreeview.c:816 msgid "Color to use for even rows" msgstr "Kleur wat vir ewegetal-rye gebruik word" -#: gtk/gtktreeview.c:831 +#: gtk/gtktreeview.c:822 msgid "Odd Row Color" msgstr "Onewegetal-ry se kleur" -#: gtk/gtktreeview.c:832 +#: gtk/gtktreeview.c:823 msgid "Color to use for odd rows" msgstr "Kleur wat vir onewegetal-rye gebruik word" -#: gtk/gtktreeview.c:838 +#: gtk/gtktreeview.c:829 msgid "Row Ending details" msgstr "" -#: gtk/gtktreeview.c:839 +#: gtk/gtktreeview.c:830 msgid "Enable extended row background theming" msgstr "" -#: gtk/gtktreeview.c:845 +#: gtk/gtktreeview.c:836 #, fuzzy msgid "Grid line width" msgstr "Fokus op reëlwydte" -#: gtk/gtktreeview.c:846 +#: gtk/gtktreeview.c:837 #, fuzzy msgid "Width, in pixels, of the tree view grid lines" msgstr "Wydte in pixels van die fokusaanwyserlyn" -#: gtk/gtktreeview.c:852 +#: gtk/gtktreeview.c:843 #, fuzzy msgid "Tree line width" msgstr "Die vaste wydte" -#: gtk/gtktreeview.c:853 +#: gtk/gtktreeview.c:844 #, fuzzy msgid "Width, in pixels, of the tree view lines" msgstr "Wydte in pixels van die fokusaanwyserlyn" -#: gtk/gtktreeview.c:859 +#: gtk/gtktreeview.c:850 #, fuzzy msgid "Grid line pattern" msgstr "Fokuslyn-stippelpatroon" -#: gtk/gtktreeview.c:860 +#: gtk/gtktreeview.c:851 #, fuzzy msgid "Dash pattern used to draw the tree view grid lines" msgstr "Stippelpatroon wat gebruik moet word om die fokusaanwyser te teken" -#: gtk/gtktreeview.c:866 +#: gtk/gtktreeview.c:857 #, fuzzy msgid "Tree line pattern" msgstr "Fokuslyn-stippelpatroon" -#: gtk/gtktreeview.c:867 +#: gtk/gtktreeview.c:858 #, fuzzy msgid "Dash pattern used to draw the tree view lines" msgstr "Stippelpatroon wat gebruik moet word om die fokusaanwyser te teken" -#: gtk/gtktreeviewcolumn.c:192 +#: gtk/gtktreeviewcolumn.c:193 msgid "Whether to display the column" msgstr "Of die kolom vertoon moet word" -#: gtk/gtktreeviewcolumn.c:199 gtk/gtkwindow.c:537 +#: gtk/gtktreeviewcolumn.c:200 gtk/gtkwindow.c:537 msgid "Resizable" msgstr "Skaleerbaar" -#: gtk/gtktreeviewcolumn.c:200 +#: gtk/gtktreeviewcolumn.c:201 msgid "Column is user-resizable" msgstr "Kolomme is gebruikerskaleerbaar" -#: gtk/gtktreeviewcolumn.c:208 +#: gtk/gtktreeviewcolumn.c:209 msgid "Current width of the column" msgstr "Huidige wydte van die kolom" -#: gtk/gtktreeviewcolumn.c:217 +#: gtk/gtktreeviewcolumn.c:218 msgid "Space which is inserted between cells" msgstr "" -#: gtk/gtktreeviewcolumn.c:225 +#: gtk/gtktreeviewcolumn.c:226 msgid "Sizing" msgstr "Skalering" -#: gtk/gtktreeviewcolumn.c:226 +#: gtk/gtktreeviewcolumn.c:227 msgid "Resize mode of the column" msgstr "Skaleermodus van die kolom" -#: gtk/gtktreeviewcolumn.c:234 +#: gtk/gtktreeviewcolumn.c:235 msgid "Fixed Width" msgstr "Vaste wydte" -#: gtk/gtktreeviewcolumn.c:235 +#: gtk/gtktreeviewcolumn.c:236 msgid "Current fixed width of the column" msgstr "Huidige vaste wydte van die kolom" -#: gtk/gtktreeviewcolumn.c:244 +#: gtk/gtktreeviewcolumn.c:245 msgid "Minimum Width" msgstr "minimum wydte" -#: gtk/gtktreeviewcolumn.c:245 +#: gtk/gtktreeviewcolumn.c:246 msgid "Minimum allowed width of the column" msgstr "minimum toegelate wydte van die kolom" -#: gtk/gtktreeviewcolumn.c:254 +#: gtk/gtktreeviewcolumn.c:255 msgid "Maximum Width" msgstr "maksimum wydte" -#: gtk/gtktreeviewcolumn.c:255 +#: gtk/gtktreeviewcolumn.c:256 msgid "Maximum allowed width of the column" msgstr "maksimum toegelate wydte van die kolom" -#: gtk/gtktreeviewcolumn.c:265 +#: gtk/gtktreeviewcolumn.c:266 msgid "Title to appear in column header" msgstr "Titel wat in die kolomkop moet verskyn" -#: gtk/gtktreeviewcolumn.c:273 +#: gtk/gtktreeviewcolumn.c:274 msgid "Column gets share of extra width allocated to the widget" msgstr "Kolom kry 'n deel van ekstra wydte wat aan die dingesie toegeken word" -#: gtk/gtktreeviewcolumn.c:280 +#: gtk/gtktreeviewcolumn.c:281 msgid "Clickable" msgstr "Kliekbaar" -#: gtk/gtktreeviewcolumn.c:281 +#: gtk/gtktreeviewcolumn.c:282 msgid "Whether the header can be clicked" msgstr "Of die kop gekliek kan word" -#: gtk/gtktreeviewcolumn.c:289 +#: gtk/gtktreeviewcolumn.c:290 msgid "Widget" msgstr "Dingesie" -#: gtk/gtktreeviewcolumn.c:290 +#: gtk/gtktreeviewcolumn.c:291 msgid "Widget to put in column header button instead of column title" msgstr "Dingesie om in kolomkop in die plek van die kolomtitel te sit" -#: gtk/gtktreeviewcolumn.c:298 +#: gtk/gtktreeviewcolumn.c:299 msgid "X Alignment of the column header text or widget" msgstr "x-gerigtheid van die kolomkopteks of -dingesie" -#: gtk/gtktreeviewcolumn.c:308 +#: gtk/gtktreeviewcolumn.c:309 msgid "Whether the column can be reordered around the headers" msgstr "Of die kolom rondom die koppe hersorteer kan word" -#: gtk/gtktreeviewcolumn.c:315 +#: gtk/gtktreeviewcolumn.c:316 msgid "Sort indicator" msgstr "Soorteeraanwyser" -#: gtk/gtktreeviewcolumn.c:316 +#: gtk/gtktreeviewcolumn.c:317 msgid "Whether to show a sort indicator" msgstr "Of die sorteeraanwyser vertoon moet word" -#: gtk/gtktreeviewcolumn.c:323 +#: gtk/gtktreeviewcolumn.c:324 msgid "Sort order" msgstr "Sorteervolgorde" -#: gtk/gtktreeviewcolumn.c:324 +#: gtk/gtktreeviewcolumn.c:325 msgid "Sort direction the sort indicator should indicate" msgstr "Sorteerrigting wat die sorteeraanwyser moet aandui" +#: gtk/gtktreeviewcolumn.c:341 +#, fuzzy +msgid "Sort column ID" +msgstr "Tekskolom" + +#: gtk/gtktreeviewcolumn.c:342 +msgid "Logical sort column ID this column sorts on when selected for sorting" +msgstr "" + #: gtk/gtkuimanager.c:223 msgid "Whether tearoff menu items should be added to menus" msgstr "Of afskeurkieslysitems by kieslyste gevoeg moet word" @@ -6989,27 +7136,27 @@ msgstr "" msgid "Determines how the shadowed box around the viewport is drawn" msgstr "Bepaal hoe die gearseerde kassie rondom die aansigpunt geteken word" -#: gtk/gtkwidget.c:483 +#: gtk/gtkwidget.c:485 msgid "Widget name" msgstr "Dingesienaam" -#: gtk/gtkwidget.c:484 +#: gtk/gtkwidget.c:486 msgid "The name of the widget" msgstr "Die naam van die dingesie" -#: gtk/gtkwidget.c:490 +#: gtk/gtkwidget.c:492 msgid "Parent widget" msgstr "Ouerdingesie" -#: gtk/gtkwidget.c:491 +#: gtk/gtkwidget.c:493 msgid "The parent widget of this widget. Must be a Container widget" msgstr "Die ouerdingesie van hierdie dingesie. Moet 'n houerdingesie wees" -#: gtk/gtkwidget.c:498 +#: gtk/gtkwidget.c:500 msgid "Width request" msgstr "Wydteversoek" -#: gtk/gtkwidget.c:499 +#: gtk/gtkwidget.c:501 msgid "" "Override for width request of the widget, or -1 if natural request should be " "used" @@ -7017,11 +7164,11 @@ msgstr "" "Oorheers die wydteversoek van die dingesie, of -1 indien natuurlike versoek " "gebruik moet word" -#: gtk/gtkwidget.c:507 +#: gtk/gtkwidget.c:509 msgid "Height request" msgstr "Hoogteversoek" -#: gtk/gtkwidget.c:508 +#: gtk/gtkwidget.c:510 msgid "" "Override for height request of the widget, or -1 if natural request should " "be used" @@ -7029,85 +7176,85 @@ msgstr "" "Oorheers die hoogteversoek van die dingesie, of -1 indien natuurlike versoek " "gebruik moet word" -#: gtk/gtkwidget.c:517 +#: gtk/gtkwidget.c:519 msgid "Whether the widget is visible" msgstr "Of die dingesie sigbaar is" -#: gtk/gtkwidget.c:524 +#: gtk/gtkwidget.c:526 msgid "Whether the widget responds to input" msgstr "Of die dingesie reageer op toevoer" -#: gtk/gtkwidget.c:530 +#: gtk/gtkwidget.c:532 msgid "Application paintable" msgstr "Toepassing verfbaar" -#: gtk/gtkwidget.c:531 +#: gtk/gtkwidget.c:533 msgid "Whether the application will paint directly on the widget" msgstr "Of die toepassing direk op die dingesie sal verf" -#: gtk/gtkwidget.c:537 +#: gtk/gtkwidget.c:539 msgid "Can focus" msgstr "Kan fokus" -#: gtk/gtkwidget.c:538 +#: gtk/gtkwidget.c:540 msgid "Whether the widget can accept the input focus" msgstr "Of die dingesie die toevoerfokus kan aanvaar" -#: gtk/gtkwidget.c:544 +#: gtk/gtkwidget.c:546 msgid "Has focus" msgstr "Het fokus" -#: gtk/gtkwidget.c:545 +#: gtk/gtkwidget.c:547 msgid "Whether the widget has the input focus" msgstr "Of die dingesie die toevoerfokus het" -#: gtk/gtkwidget.c:551 +#: gtk/gtkwidget.c:553 msgid "Is focus" msgstr "Is fokus" -#: gtk/gtkwidget.c:552 +#: gtk/gtkwidget.c:554 msgid "Whether the widget is the focus widget within the toplevel" msgstr "Of die dingesie die fokusdingesie binne die bokant is" -#: gtk/gtkwidget.c:558 +#: gtk/gtkwidget.c:560 msgid "Can default" msgstr "Kan verstek wees" -#: gtk/gtkwidget.c:559 +#: gtk/gtkwidget.c:561 msgid "Whether the widget can be the default widget" msgstr "Of die dingesie die verstekdingesie kan wees" -#: gtk/gtkwidget.c:565 +#: gtk/gtkwidget.c:567 msgid "Has default" msgstr "Het verstek" -#: gtk/gtkwidget.c:566 +#: gtk/gtkwidget.c:568 msgid "Whether the widget is the default widget" msgstr "Of die dingesie die verstekdingesie is" -#: gtk/gtkwidget.c:572 +#: gtk/gtkwidget.c:574 msgid "Receives default" msgstr "Ontvang verstek" -#: gtk/gtkwidget.c:573 +#: gtk/gtkwidget.c:575 msgid "If TRUE, the widget will receive the default action when it is focused" msgstr "" "Indien WAAR sal die dingesie die verstekaksie ontvang wanneer dit gefokus " "word" -#: gtk/gtkwidget.c:579 +#: gtk/gtkwidget.c:581 msgid "Composite child" msgstr "Saamgestelde kind" -#: gtk/gtkwidget.c:580 +#: gtk/gtkwidget.c:582 msgid "Whether the widget is part of a composite widget" msgstr "Of die dingesie deel van 'n saamgestelde dingesie is" -#: gtk/gtkwidget.c:586 +#: gtk/gtkwidget.c:588 msgid "Style" msgstr "Styl" -#: gtk/gtkwidget.c:587 +#: gtk/gtkwidget.c:589 msgid "" "The style of the widget, which contains information about how it will look " "(colors etc)" @@ -7115,91 +7262,101 @@ msgstr "" "Die styl van die dingesie, waarin inligting oor hoe dit lyk (kleure ens) " "vervat is" -#: gtk/gtkwidget.c:593 +#: gtk/gtkwidget.c:595 msgid "Events" msgstr "Gebeure" -#: gtk/gtkwidget.c:594 +#: gtk/gtkwidget.c:596 msgid "The event mask that decides what kind of GdkEvents this widget gets" msgstr "" "Die gebeuremasker wat besluit watter soort GdkEvents hierdie dingesie kry" -#: gtk/gtkwidget.c:601 +#: gtk/gtkwidget.c:603 msgid "Extension events" msgstr "Uitbreidinggebeure" -#: gtk/gtkwidget.c:602 +#: gtk/gtkwidget.c:604 msgid "The mask that decides what kind of extension events this widget gets" msgstr "Die masker wat besluit watter soort uitbreiding hierdie dingesie kry" -#: gtk/gtkwidget.c:609 +#: gtk/gtkwidget.c:611 msgid "No show all" msgstr "Glad nie vertoon nie" -#: gtk/gtkwidget.c:610 +#: gtk/gtkwidget.c:612 msgid "Whether gtk_widget_show_all() should not affect this widget" msgstr "" "Of gtk_widget_show_all() nie 'n uitwerking op hierdie dingesie moet hê nie" -#: gtk/gtkwidget.c:633 +#: gtk/gtkwidget.c:635 #, fuzzy msgid "Whether this widget has a tooltip" msgstr "Of die dingesie die toevoerfokus het" -#: gtk/gtkwidget.c:689 +#: gtk/gtkwidget.c:691 #, fuzzy msgid "Window" msgstr "Venstersoort" -#: gtk/gtkwidget.c:690 +#: gtk/gtkwidget.c:692 msgid "The widget's window if it is realized" msgstr "" -#: gtk/gtkwidget.c:2212 +#: gtk/gtkwidget.c:706 +#, fuzzy +msgid "Double Buffered" +msgstr "Buffer" + +#: gtk/gtkwidget.c:707 +#, fuzzy +msgid "Whether or not the widget is double buffered" +msgstr "Of die aksie sigbaar is." + +#: gtk/gtkwidget.c:2229 msgid "Interior Focus" msgstr "Binnefokus" -#: gtk/gtkwidget.c:2213 +#: gtk/gtkwidget.c:2230 msgid "Whether to draw the focus indicator inside widgets" msgstr "Of die fokusaanwyser binne dingesies geteken moet word" -#: gtk/gtkwidget.c:2219 +#: gtk/gtkwidget.c:2236 msgid "Focus linewidth" msgstr "Fokus op reëlwydte" -#: gtk/gtkwidget.c:2220 +#: gtk/gtkwidget.c:2237 msgid "Width, in pixels, of the focus indicator line" msgstr "Wydte in pixels van die fokusaanwyserlyn" -#: gtk/gtkwidget.c:2226 +#: gtk/gtkwidget.c:2243 msgid "Focus line dash pattern" msgstr "Fokuslyn-stippelpatroon" -#: gtk/gtkwidget.c:2227 +#: gtk/gtkwidget.c:2244 msgid "Dash pattern used to draw the focus indicator" msgstr "Stippelpatroon wat gebruik moet word om die fokusaanwyser te teken" -#: gtk/gtkwidget.c:2232 +#: gtk/gtkwidget.c:2249 msgid "Focus padding" msgstr "Fokusopvulling" -#: gtk/gtkwidget.c:2233 +#: gtk/gtkwidget.c:2250 msgid "Width, in pixels, between focus indicator and the widget 'box'" msgstr "Wydte in pixels tussen fokusaanwyser en die dingesie-kassie" -#: gtk/gtkwidget.c:2238 +#: gtk/gtkwidget.c:2255 msgid "Cursor color" msgstr "Wyserkleur" -#: gtk/gtkwidget.c:2239 +#: gtk/gtkwidget.c:2256 msgid "Color with which to draw insertion cursor" msgstr "Kleure waarmee die invoegwyser geteken moet word" -#: gtk/gtkwidget.c:2244 +#: gtk/gtkwidget.c:2261 msgid "Secondary cursor color" msgstr "Sekondêrewyser-kleur" -#: gtk/gtkwidget.c:2245 +#: gtk/gtkwidget.c:2262 msgid "" "Color with which to draw the secondary insertion cursor when editing mixed " "right-to-left and left-to-right text" @@ -7207,88 +7364,88 @@ msgstr "" "Kleur waarmee die sekondêre invoegwyser geteken moet word wanneer gemengde " "regs-na-links- en links-na-regs-teks geredigeer word" -#: gtk/gtkwidget.c:2250 +#: gtk/gtkwidget.c:2267 msgid "Cursor line aspect ratio" msgstr "Wyserlyn-aspekratio" -#: gtk/gtkwidget.c:2251 +#: gtk/gtkwidget.c:2268 msgid "Aspect ratio with which to draw insertion cursor" msgstr "Aspekratio waarmee die invoegwyser geteken moet word" -#: gtk/gtkwidget.c:2265 +#: gtk/gtkwidget.c:2282 #, fuzzy msgid "Draw Border" msgstr "Oortjiegrens" -#: gtk/gtkwidget.c:2266 +#: gtk/gtkwidget.c:2283 msgid "Size of areas outside the widget's allocation to draw" msgstr "" -#: gtk/gtkwidget.c:2279 +#: gtk/gtkwidget.c:2296 #, fuzzy msgid "Unvisited Link Color" msgstr "Huidige kleur" -#: gtk/gtkwidget.c:2280 +#: gtk/gtkwidget.c:2297 #, fuzzy msgid "Color of unvisited links" msgstr "Die titel van die fontkies-dialoog" -#: gtk/gtkwidget.c:2293 +#: gtk/gtkwidget.c:2310 #, fuzzy msgid "Visited Link Color" msgstr "Huidige kleur" -#: gtk/gtkwidget.c:2294 +#: gtk/gtkwidget.c:2311 #, fuzzy msgid "Color of visited links" msgstr "Die titel van die fontkies-dialoog" -#: gtk/gtkwidget.c:2308 +#: gtk/gtkwidget.c:2325 #, fuzzy msgid "Wide Separators" msgstr "Gebruik skeier" -#: gtk/gtkwidget.c:2309 +#: gtk/gtkwidget.c:2326 msgid "" "Whether separators have configurable width and should be drawn using a box " "instead of a line" msgstr "" -#: gtk/gtkwidget.c:2323 +#: gtk/gtkwidget.c:2340 #, fuzzy msgid "Separator Width" msgstr "Vertikaleskeier-wydte" -#: gtk/gtkwidget.c:2324 +#: gtk/gtkwidget.c:2341 msgid "The width of separators if wide-separators is TRUE" msgstr "" -#: gtk/gtkwidget.c:2338 +#: gtk/gtkwidget.c:2355 #, fuzzy msgid "Separator Height" msgstr "Verstekhoogte" -#: gtk/gtkwidget.c:2339 +#: gtk/gtkwidget.c:2356 msgid "The height of separators if \"wide-separators\" is TRUE" msgstr "" -#: gtk/gtkwidget.c:2353 +#: gtk/gtkwidget.c:2370 #, fuzzy msgid "Horizontal Scroll Arrow Length" msgstr "Horisontalerolstaaf-beleid" -#: gtk/gtkwidget.c:2354 +#: gtk/gtkwidget.c:2371 #, fuzzy msgid "The length of horizontal scroll arrows" msgstr "Wanneer die horisontale rolstaaf vertoon word" -#: gtk/gtkwidget.c:2368 +#: gtk/gtkwidget.c:2385 #, fuzzy msgid "Vertical Scroll Arrow Length" msgstr "Vertikalerolstaaf-beleid" -#: gtk/gtkwidget.c:2369 +#: gtk/gtkwidget.c:2386 #, fuzzy msgid "The length of vertical scroll arrows" msgstr "Wanneer die vertikale rolstaaf vertoon word" diff --git a/po-properties/am.po b/po-properties/am.po index 01af3677ff..d80430f4e0 100644 --- a/po-properties/am.po +++ b/po-properties/am.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: gtk+ 2.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-06-15 20:53-0400\n" +"POT-Creation-Date: 2009-09-30 17:31-0400\n" "PO-Revision-Date: 2003-01-14 11:02+EDT\n" "Last-Translator: Ge'ez Frontier Foundation \n" "Language-Team: Amharic \n" @@ -16,6 +16,14 @@ msgstr "" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" +#: gdk-pixbuf/gdk-pixbuf-simple-anim.c:165 +msgid "Loop" +msgstr "" + +#: gdk-pixbuf/gdk-pixbuf-simple-anim.c:166 +msgid "Whether the animation should loop when it reaches the end" +msgstr "" + #: gdk-pixbuf/gdk-pixbuf.c:89 msgid "Number of Channels" msgstr "" @@ -49,7 +57,7 @@ msgstr "" msgid "The number of bits per sample" msgstr "" -#: gdk-pixbuf/gdk-pixbuf.c:132 gtk/gtklayout.c:632 gtk/gtktreeviewcolumn.c:207 +#: gdk-pixbuf/gdk-pixbuf.c:132 gtk/gtklayout.c:632 gtk/gtktreeviewcolumn.c:208 msgid "Width" msgstr "ስፋት" @@ -91,12 +99,12 @@ msgstr "" msgid "The default display for GDK" msgstr "" -#: gdk/gdkpango.c:537 gtk/gtkinvisible.c:86 gtk/gtkmountoperation.c:155 -#: gtk/gtkstatusicon.c:277 gtk/gtkwindow.c:614 +#: gdk/gdkpango.c:538 gtk/gtkinvisible.c:86 gtk/gtkmountoperation.c:176 +#: gtk/gtkstatusicon.c:280 gtk/gtkwindow.c:614 msgid "Screen" msgstr "እስክሪን" -#: gdk/gdkpango.c:538 +#: gdk/gdkpango.c:539 msgid "the GdkScreen for the renderer" msgstr "" @@ -116,6 +124,11 @@ msgstr "" msgid "The resolution for fonts on the screen" msgstr "" +#: gdk/gdkwindow.c:472 gdk/gdkwindow.c:473 +#, fuzzy +msgid "Cursor" +msgstr "የመጠቆሚያዋ አበራርና አጠፋፍ" + #: gtk/gtkaboutdialog.c:239 msgid "Program name" msgstr "" @@ -257,7 +270,7 @@ msgid "A unique name for the action." msgstr "" #: gtk/gtkaction.c:198 gtk/gtkbutton.c:219 gtk/gtkexpander.c:195 -#: gtk/gtkframe.c:105 gtk/gtklabel.c:495 gtk/gtkmenuitem.c:300 +#: gtk/gtkframe.c:105 gtk/gtklabel.c:496 gtk/gtkmenuitem.c:305 #: gtk/gtktoolbutton.c:202 msgid "Label" msgstr "መለያ" @@ -291,33 +304,33 @@ msgstr "" msgid "The stock icon displayed in widgets representing this action." msgstr "" -#: gtk/gtkaction.c:261 gtk/gtkstatusicon.c:250 +#: gtk/gtkaction.c:261 gtk/gtkstatusicon.c:253 #, fuzzy msgid "GIcon" msgstr "ምልክት" #: gtk/gtkaction.c:262 gtk/gtkcellrendererpixbuf.c:206 gtk/gtkimage.c:248 -#: gtk/gtkstatusicon.c:251 +#: gtk/gtkstatusicon.c:254 msgid "The GIcon being displayed" msgstr "" #: gtk/gtkaction.c:282 gtk/gtkcellrendererpixbuf.c:171 gtk/gtkimage.c:230 -#: gtk/gtkprinter.c:172 gtk/gtkstatusicon.c:234 gtk/gtkwindow.c:606 +#: gtk/gtkprinter.c:172 gtk/gtkstatusicon.c:237 gtk/gtkwindow.c:606 #, fuzzy msgid "Icon Name" msgstr "የፊደሉ ቅርጽ ስም" #: gtk/gtkaction.c:283 gtk/gtkcellrendererpixbuf.c:172 gtk/gtkimage.c:231 -#: gtk/gtkstatusicon.c:235 +#: gtk/gtkstatusicon.c:238 #, fuzzy msgid "The name of the icon from the icon theme" msgstr "የጽሑፉ መለያ" -#: gtk/gtkaction.c:290 gtk/gtktoolitem.c:176 +#: gtk/gtkaction.c:290 gtk/gtktoolitem.c:192 msgid "Visible when horizontal" msgstr "" -#: gtk/gtkaction.c:291 gtk/gtktoolitem.c:177 +#: gtk/gtkaction.c:291 gtk/gtktoolitem.c:193 msgid "" "Whether the toolbar item is visible when the toolbar is in a horizontal " "orientation." @@ -334,17 +347,17 @@ msgid "" "overflow menu." msgstr "" -#: gtk/gtkaction.c:314 gtk/gtktoolitem.c:183 +#: gtk/gtkaction.c:314 gtk/gtktoolitem.c:199 msgid "Visible when vertical" msgstr "" -#: gtk/gtkaction.c:315 gtk/gtktoolitem.c:184 +#: gtk/gtkaction.c:315 gtk/gtktoolitem.c:200 msgid "" "Whether the toolbar item is visible when the toolbar is in a vertical " "orientation." msgstr "" -#: gtk/gtkaction.c:322 gtk/gtktoolitem.c:190 +#: gtk/gtkaction.c:322 gtk/gtktoolitem.c:206 msgid "Is important" msgstr "" @@ -363,7 +376,7 @@ msgid "When TRUE, empty menu proxies for this action are hidden." msgstr "" #: gtk/gtkaction.c:338 gtk/gtkactiongroup.c:177 gtk/gtkcellrenderer.c:193 -#: gtk/gtkwidget.c:523 +#: gtk/gtkwidget.c:525 msgid "Sensitive" msgstr "" @@ -371,8 +384,8 @@ msgstr "" msgid "Whether the action is enabled." msgstr "" -#: gtk/gtkaction.c:345 gtk/gtkactiongroup.c:184 gtk/gtkstatusicon.c:293 -#: gtk/gtktreeviewcolumn.c:191 gtk/gtkwidget.c:516 +#: gtk/gtkaction.c:345 gtk/gtkactiongroup.c:184 gtk/gtkstatusicon.c:296 +#: gtk/gtktreeviewcolumn.c:192 gtk/gtkwidget.c:518 msgid "Visible" msgstr "የሚታይ" @@ -403,6 +416,23 @@ msgstr "" msgid "Whether the action group is visible." msgstr "" +#: gtk/gtkactivatable.c:304 +#, fuzzy +msgid "Related Action" +msgstr "ምልክት" + +#: gtk/gtkactivatable.c:305 +msgid "The action this activatable will activate and receive updates from" +msgstr "" + +#: gtk/gtkactivatable.c:327 +msgid "Use Action Appearance" +msgstr "" + +#: gtk/gtkactivatable.c:328 +msgid "Whether to use the related actions appearance properties" +msgstr "" + #: gtk/gtkadjustment.c:93 gtk/gtkcellrendererprogress.c:128 #: gtk/gtkscalebutton.c:206 gtk/gtkspinbutton.c:269 msgid "Value" @@ -552,7 +582,7 @@ msgstr "" msgid "Appearance of the shadow surrounding the arrow" msgstr "" -#: gtk/gtkarrow.c:92 gtk/gtkmenu.c:689 gtk/gtkmenuitem.c:363 +#: gtk/gtkarrow.c:92 gtk/gtkmenu.c:711 gtk/gtkmenuitem.c:368 #, fuzzy msgid "Arrow Scaling" msgstr "ክፍተት" @@ -660,60 +690,60 @@ msgstr "መጠን" msgid "Whether all required fields on the page have been filled out" msgstr "" -#: gtk/gtkbbox.c:99 +#: gtk/gtkbbox.c:101 msgid "Minimum child width" msgstr "" -#: gtk/gtkbbox.c:100 +#: gtk/gtkbbox.c:102 msgid "Minimum width of buttons inside the box" msgstr "" -#: gtk/gtkbbox.c:108 +#: gtk/gtkbbox.c:110 msgid "Minimum child height" msgstr "" -#: gtk/gtkbbox.c:109 +#: gtk/gtkbbox.c:111 msgid "Minimum height of buttons inside the box" msgstr "" -#: gtk/gtkbbox.c:117 +#: gtk/gtkbbox.c:119 msgid "Child internal width padding" msgstr "" -#: gtk/gtkbbox.c:118 +#: gtk/gtkbbox.c:120 msgid "Amount to increase child's size on either side" msgstr "" -#: gtk/gtkbbox.c:126 +#: gtk/gtkbbox.c:128 msgid "Child internal height padding" msgstr "" -#: gtk/gtkbbox.c:127 +#: gtk/gtkbbox.c:129 msgid "Amount to increase child's size on the top and bottom" msgstr "" -#: gtk/gtkbbox.c:135 +#: gtk/gtkbbox.c:137 msgid "Layout style" msgstr "የእቅድ ዓይነት" -#: gtk/gtkbbox.c:136 +#: gtk/gtkbbox.c:138 msgid "" "How to layout the buttons in the box. Possible values are default, spread, " "edge, start and end" msgstr "" -#: gtk/gtkbbox.c:144 +#: gtk/gtkbbox.c:146 msgid "Secondary" msgstr "" -#: gtk/gtkbbox.c:145 +#: gtk/gtkbbox.c:147 msgid "" "If TRUE, the child appears in a secondary group of children, suitable for, e." "g., help buttons" msgstr "" -#: gtk/gtkbox.c:130 gtk/gtkexpander.c:219 gtk/gtkiconview.c:664 -#: gtk/gtktreeviewcolumn.c:216 +#: gtk/gtkbox.c:130 gtk/gtkexpander.c:219 gtk/gtkiconview.c:665 +#: gtk/gtktreeviewcolumn.c:217 msgid "Spacing" msgstr "ክፍተት" @@ -731,7 +761,7 @@ msgid "Whether the children should all be the same size" msgstr "" #: gtk/gtkbox.c:148 gtk/gtkpreview.c:101 gtk/gtktoolbar.c:565 -#: gtk/gtktreeviewcolumn.c:272 +#: gtk/gtktreeviewcolumn.c:273 msgid "Expand" msgstr "" @@ -790,13 +820,13 @@ msgid "" "widget" msgstr "" -#: gtk/gtkbutton.c:227 gtk/gtkexpander.c:203 gtk/gtklabel.c:516 -#: gtk/gtkmenuitem.c:315 gtk/gtktoolbutton.c:209 +#: gtk/gtkbutton.c:227 gtk/gtkexpander.c:203 gtk/gtklabel.c:517 +#: gtk/gtkmenuitem.c:320 gtk/gtktoolbutton.c:209 msgid "Use underline" msgstr "" -#: gtk/gtkbutton.c:228 gtk/gtkexpander.c:204 gtk/gtklabel.c:517 -#: gtk/gtkmenuitem.c:316 +#: gtk/gtkbutton.c:228 gtk/gtkexpander.c:204 gtk/gtklabel.c:518 +#: gtk/gtkmenuitem.c:321 msgid "" "If set, an underline in the text indicates the next character should be used " "for the mnemonic accelerator key" @@ -811,7 +841,7 @@ msgid "" "If set, the label is used to pick a stock item instead of being displayed" msgstr "" -#: gtk/gtkbutton.c:243 gtk/gtkcombobox.c:789 gtk/gtkfilechooserbutton.c:393 +#: gtk/gtkbutton.c:243 gtk/gtkcombobox.c:791 gtk/gtkfilechooserbutton.c:393 msgid "Focus on click" msgstr "" @@ -900,7 +930,7 @@ msgid "" "rectangle" msgstr "" -#: gtk/gtkbutton.c:485 gtk/gtkentry.c:658 gtk/gtkentry.c:1682 +#: gtk/gtkbutton.c:485 gtk/gtkentry.c:689 gtk/gtkentry.c:1713 #, fuzzy msgid "Inner Border" msgstr "ቅደም ተከተል" @@ -1130,36 +1160,36 @@ msgstr "" msgid "Whether this tag affects the cell background color" msgstr "" -#: gtk/gtkcellrendereraccel.c:113 +#: gtk/gtkcellrendereraccel.c:114 msgid "Accelerator key" msgstr "" -#: gtk/gtkcellrendereraccel.c:114 +#: gtk/gtkcellrendereraccel.c:115 #, fuzzy msgid "The keyval of the accelerator" msgstr "የጽሑፉ መለያ" -#: gtk/gtkcellrendereraccel.c:130 +#: gtk/gtkcellrendereraccel.c:131 msgid "Accelerator modifiers" msgstr "" -#: gtk/gtkcellrendereraccel.c:131 +#: gtk/gtkcellrendereraccel.c:132 msgid "The modifier mask of the accelerator" msgstr "" -#: gtk/gtkcellrendereraccel.c:148 +#: gtk/gtkcellrendereraccel.c:149 msgid "Accelerator keycode" msgstr "" -#: gtk/gtkcellrendereraccel.c:149 +#: gtk/gtkcellrendereraccel.c:150 msgid "The hardware keycode of the accelerator" msgstr "" -#: gtk/gtkcellrendereraccel.c:168 +#: gtk/gtkcellrendereraccel.c:169 msgid "Accelerator Mode" msgstr "" -#: gtk/gtkcellrendereraccel.c:169 +#: gtk/gtkcellrendereraccel.c:170 #, fuzzy msgid "The type of accelerators" msgstr "የመስኮቱ ዓይነት" @@ -1214,7 +1244,7 @@ msgstr "" msgid "Pixbuf for closed expander" msgstr "" -#: gtk/gtkcellrendererpixbuf.c:135 gtk/gtkimage.c:172 gtk/gtkstatusicon.c:226 +#: gtk/gtkcellrendererpixbuf.c:135 gtk/gtkimage.c:172 gtk/gtkstatusicon.c:229 msgid "Stock ID" msgstr "" @@ -1223,7 +1253,7 @@ msgid "The stock ID of the stock icon to render" msgstr "" #: gtk/gtkcellrendererpixbuf.c:143 gtk/gtkrecentmanager.c:245 -#: gtk/gtkstatusicon.c:267 +#: gtk/gtkstatusicon.c:270 msgid "Size" msgstr "መጠን" @@ -1256,8 +1286,8 @@ msgid "Value of the progress bar" msgstr "" #: gtk/gtkcellrendererprogress.c:146 gtk/gtkcellrenderertext.c:195 -#: gtk/gtkentry.c:701 gtk/gtkmessagedialog.c:153 gtk/gtkprogressbar.c:184 -#: gtk/gtktextbuffer.c:198 +#: gtk/gtkentry.c:732 gtk/gtkentrybuffer.c:353 gtk/gtkmessagedialog.c:153 +#: gtk/gtkprogressbar.c:184 gtk/gtktextbuffer.c:198 msgid "Text" msgstr "ጽሑፍ" @@ -1295,7 +1325,7 @@ msgid "The vertical text alignment, from 0 (top) to 1 (bottom)." msgstr "" #: gtk/gtkcellrendererprogress.c:221 gtk/gtkiconview.c:729 -#: gtk/gtkorientable.c:74 gtk/gtkprogressbar.c:126 gtk/gtkstatusicon.c:325 +#: gtk/gtkorientable.c:74 gtk/gtkprogressbar.c:126 gtk/gtkstatusicon.c:328 #: gtk/gtktrayicon-x11.c:110 msgid "Orientation" msgstr "አቀማመጥ" @@ -1341,7 +1371,7 @@ msgstr "" msgid "Marked up text to render" msgstr "" -#: gtk/gtkcellrenderertext.c:211 gtk/gtklabel.c:502 +#: gtk/gtkcellrenderertext.c:211 gtk/gtklabel.c:503 msgid "Attributes" msgstr "" @@ -1389,12 +1419,12 @@ msgstr "የፊት ለፊቱ ቀለም" msgid "Foreground color as a GdkColor" msgstr "" -#: gtk/gtkcellrenderertext.c:261 gtk/gtkentry.c:625 gtk/gtktexttag.c:251 -#: gtk/gtktextview.c:573 +#: gtk/gtkcellrenderertext.c:261 gtk/gtkentry.c:656 gtk/gtktexttag.c:251 +#: gtk/gtktextview.c:574 msgid "Editable" msgstr "" -#: gtk/gtkcellrenderertext.c:262 gtk/gtktexttag.c:252 gtk/gtktextview.c:574 +#: gtk/gtkcellrenderertext.c:262 gtk/gtktexttag.c:252 gtk/gtktextview.c:575 msgid "Whether the text can be modified by the user" msgstr "" @@ -1496,7 +1526,7 @@ msgid "" "probably don't need it" msgstr "" -#: gtk/gtkcellrenderertext.c:411 gtk/gtklabel.c:627 gtk/gtkprogressbar.c:206 +#: gtk/gtkcellrenderertext.c:411 gtk/gtklabel.c:628 gtk/gtkprogressbar.c:206 msgid "Ellipsize" msgstr "" @@ -1507,11 +1537,11 @@ msgid "" msgstr "" #: gtk/gtkcellrenderertext.c:431 gtk/gtkfilechooserbutton.c:421 -#: gtk/gtklabel.c:647 +#: gtk/gtklabel.c:648 msgid "Width In Characters" msgstr "" -#: gtk/gtkcellrenderertext.c:432 gtk/gtklabel.c:648 +#: gtk/gtkcellrenderertext.c:432 gtk/gtklabel.c:649 msgid "The desired width of the label, in characters" msgstr "" @@ -1525,7 +1555,7 @@ msgid "" "have enough room to display the entire string" msgstr "" -#: gtk/gtkcellrenderertext.c:470 gtk/gtkcombobox.c:678 +#: gtk/gtkcellrenderertext.c:470 gtk/gtkcombobox.c:680 #, fuzzy msgid "Wrap width" msgstr "ስፋት" @@ -1534,7 +1564,7 @@ msgstr "ስፋት" msgid "The width at which the text is wrapped" msgstr "" -#: gtk/gtkcellrenderertext.c:491 gtk/gtktreeviewcolumn.c:297 +#: gtk/gtkcellrenderertext.c:491 gtk/gtktreeviewcolumn.c:298 msgid "Alignment" msgstr "ኩልኩል" @@ -1735,7 +1765,7 @@ msgstr "" msgid "Spacing around check or radio indicator" msgstr "" -#: gtk/gtkcheckmenuitem.c:98 gtk/gtkmenu.c:500 gtk/gtktoggleaction.c:119 +#: gtk/gtkcheckmenuitem.c:98 gtk/gtkmenu.c:501 gtk/gtktoggleaction.c:119 #: gtk/gtktogglebutton.c:115 gtk/gtktoggletoolbutton.c:114 msgid "Active" msgstr "" @@ -1769,7 +1799,8 @@ msgid "Whether or not to give the color an alpha value" msgstr "" #: gtk/gtkcolorbutton.c:186 gtk/gtkfilechooserbutton.c:407 -#: gtk/gtkfontbutton.c:142 gtk/gtkprintjob.c:116 gtk/gtktreeviewcolumn.c:264 +#: gtk/gtkfontbutton.c:142 gtk/gtkprintjob.c:116 gtk/gtkstatusicon.c:424 +#: gtk/gtktreeviewcolumn.c:265 msgid "Title" msgstr "አርእስት" @@ -1903,112 +1934,112 @@ msgstr "" msgid "Whether entered values must already be present in the list" msgstr "" -#: gtk/gtkcombobox.c:661 +#: gtk/gtkcombobox.c:663 msgid "ComboBox model" msgstr "" -#: gtk/gtkcombobox.c:662 +#: gtk/gtkcombobox.c:664 msgid "The model for the combo box" msgstr "" -#: gtk/gtkcombobox.c:679 +#: gtk/gtkcombobox.c:681 msgid "Wrap width for laying out the items in a grid" msgstr "" -#: gtk/gtkcombobox.c:701 +#: gtk/gtkcombobox.c:703 msgid "Row span column" msgstr "" -#: gtk/gtkcombobox.c:702 +#: gtk/gtkcombobox.c:704 msgid "TreeModel column containing the row span values" msgstr "" -#: gtk/gtkcombobox.c:723 +#: gtk/gtkcombobox.c:725 msgid "Column span column" msgstr "" -#: gtk/gtkcombobox.c:724 +#: gtk/gtkcombobox.c:726 msgid "TreeModel column containing the column span values" msgstr "" -#: gtk/gtkcombobox.c:745 +#: gtk/gtkcombobox.c:747 msgid "Active item" msgstr "" -#: gtk/gtkcombobox.c:746 +#: gtk/gtkcombobox.c:748 msgid "The item which is currently active" msgstr "" -#: gtk/gtkcombobox.c:765 gtk/gtkuimanager.c:222 +#: gtk/gtkcombobox.c:767 gtk/gtkuimanager.c:222 msgid "Add tearoffs to menus" msgstr "" -#: gtk/gtkcombobox.c:766 +#: gtk/gtkcombobox.c:768 msgid "Whether dropdowns should have a tearoff menu item" msgstr "" -#: gtk/gtkcombobox.c:781 gtk/gtkentry.c:650 +#: gtk/gtkcombobox.c:783 gtk/gtkentry.c:681 msgid "Has Frame" msgstr "ፍሬም አለ" -#: gtk/gtkcombobox.c:782 +#: gtk/gtkcombobox.c:784 msgid "Whether the combo box draws a frame around the child" msgstr "" -#: gtk/gtkcombobox.c:790 +#: gtk/gtkcombobox.c:792 msgid "Whether the combo box grabs focus when it is clicked with the mouse" msgstr "" -#: gtk/gtkcombobox.c:805 gtk/gtkmenu.c:555 +#: gtk/gtkcombobox.c:807 gtk/gtkmenu.c:556 msgid "Tearoff Title" msgstr "" -#: gtk/gtkcombobox.c:806 +#: gtk/gtkcombobox.c:808 msgid "" "A title that may be displayed by the window manager when the popup is torn-" "off" msgstr "" -#: gtk/gtkcombobox.c:823 +#: gtk/gtkcombobox.c:825 msgid "Popup shown" msgstr "" -#: gtk/gtkcombobox.c:824 +#: gtk/gtkcombobox.c:826 msgid "Whether the combo's dropdown is shown" msgstr "" -#: gtk/gtkcombobox.c:840 +#: gtk/gtkcombobox.c:842 msgid "Button Sensitivity" msgstr "" -#: gtk/gtkcombobox.c:841 +#: gtk/gtkcombobox.c:843 msgid "Whether the dropdown button is sensitive when the model is empty" msgstr "" -#: gtk/gtkcombobox.c:848 +#: gtk/gtkcombobox.c:850 msgid "Appears as list" msgstr "" -#: gtk/gtkcombobox.c:849 +#: gtk/gtkcombobox.c:851 msgid "Whether dropdowns should look like lists rather than menus" msgstr "" -#: gtk/gtkcombobox.c:865 +#: gtk/gtkcombobox.c:867 #, fuzzy msgid "Arrow Size" msgstr "ጽሑፍ አሳይ" -#: gtk/gtkcombobox.c:866 +#: gtk/gtkcombobox.c:868 msgid "The minimum size of the arrow in the combo box" msgstr "" -#: gtk/gtkcombobox.c:881 gtk/gtkentry.c:750 gtk/gtkhandlebox.c:174 +#: gtk/gtkcombobox.c:883 gtk/gtkentry.c:781 gtk/gtkhandlebox.c:174 #: gtk/gtkmenubar.c:194 gtk/gtkstatusbar.c:186 gtk/gtktoolbar.c:623 #: gtk/gtkviewport.c:122 msgid "Shadow type" msgstr "" -#: gtk/gtkcombobox.c:882 +#: gtk/gtkcombobox.c:884 msgid "Which kind of shadow to draw around the combo box" msgstr "" @@ -2084,7 +2115,7 @@ msgstr "" msgid "The dialog has a separator bar above its buttons" msgstr "" -#: gtk/gtkdialog.c:191 +#: gtk/gtkdialog.c:191 gtk/gtkinfobar.c:439 msgid "Content area border" msgstr "" @@ -2092,7 +2123,7 @@ msgstr "" msgid "Width of border around the main dialog area" msgstr "" -#: gtk/gtkdialog.c:209 +#: gtk/gtkdialog.c:209 gtk/gtkinfobar.c:456 #, fuzzy msgid "Content area spacing" msgstr "የግራ ህዳግ" @@ -2101,15 +2132,15 @@ msgstr "የግራ ህዳግ" msgid "Spacing between elements of the main dialog area" msgstr "" -#: gtk/gtkdialog.c:217 +#: gtk/gtkdialog.c:217 gtk/gtkinfobar.c:472 msgid "Button spacing" msgstr "" -#: gtk/gtkdialog.c:218 +#: gtk/gtkdialog.c:218 gtk/gtkinfobar.c:473 msgid "Spacing between buttons" msgstr "" -#: gtk/gtkdialog.c:226 +#: gtk/gtkdialog.c:226 gtk/gtkinfobar.c:488 msgid "Action area border" msgstr "" @@ -2117,368 +2148,385 @@ msgstr "" msgid "Width of border around the button area at the bottom of the dialog" msgstr "" -#: gtk/gtkentry.c:605 gtk/gtklabel.c:590 +#: gtk/gtkentry.c:628 +msgid "Text Buffer" +msgstr "" + +#: gtk/gtkentry.c:629 +msgid "Text buffer object which actually stores entry text" +msgstr "" + +#: gtk/gtkentry.c:636 gtk/gtklabel.c:591 msgid "Cursor Position" msgstr "ጠቋሚው ባለበት ቦታ" -#: gtk/gtkentry.c:606 gtk/gtklabel.c:591 +#: gtk/gtkentry.c:637 gtk/gtklabel.c:592 msgid "The current position of the insertion cursor in chars" msgstr "" -#: gtk/gtkentry.c:615 gtk/gtklabel.c:600 +#: gtk/gtkentry.c:646 gtk/gtklabel.c:601 msgid "Selection Bound" msgstr "" -#: gtk/gtkentry.c:616 gtk/gtklabel.c:601 +#: gtk/gtkentry.c:647 gtk/gtklabel.c:602 msgid "" "The position of the opposite end of the selection from the cursor in chars" msgstr "" -#: gtk/gtkentry.c:626 +#: gtk/gtkentry.c:657 msgid "Whether the entry contents can be edited" msgstr "" -#: gtk/gtkentry.c:633 +#: gtk/gtkentry.c:664 gtk/gtkentrybuffer.c:383 msgid "Maximum length" msgstr "" -#: gtk/gtkentry.c:634 +#: gtk/gtkentry.c:665 gtk/gtkentrybuffer.c:384 msgid "Maximum number of characters for this entry. Zero if no maximum" msgstr "" -#: gtk/gtkentry.c:642 +#: gtk/gtkentry.c:673 msgid "Visibility" msgstr "" -#: gtk/gtkentry.c:643 +#: gtk/gtkentry.c:674 msgid "" "FALSE displays the \"invisible char\" instead of the actual text (password " "mode)" msgstr "" -#: gtk/gtkentry.c:651 +#: gtk/gtkentry.c:682 msgid "FALSE removes outside bevel from entry" msgstr "" -#: gtk/gtkentry.c:659 +#: gtk/gtkentry.c:690 msgid "" "Border between text and frame. Overrides the inner-border style property" msgstr "" -#: gtk/gtkentry.c:666 gtk/gtkentry.c:1232 +#: gtk/gtkentry.c:697 gtk/gtkentry.c:1263 msgid "Invisible character" msgstr "" -#: gtk/gtkentry.c:667 gtk/gtkentry.c:1233 +#: gtk/gtkentry.c:698 gtk/gtkentry.c:1264 msgid "The character to use when masking entry contents (in \"password mode\")" msgstr "" -#: gtk/gtkentry.c:674 +#: gtk/gtkentry.c:705 msgid "Activates default" msgstr "" -#: gtk/gtkentry.c:675 +#: gtk/gtkentry.c:706 msgid "" "Whether to activate the default widget (such as the default button in a " "dialog) when Enter is pressed" msgstr "" -#: gtk/gtkentry.c:681 +#: gtk/gtkentry.c:712 msgid "Width in chars" msgstr "" -#: gtk/gtkentry.c:682 +#: gtk/gtkentry.c:713 msgid "Number of characters to leave space for in the entry" msgstr "" -#: gtk/gtkentry.c:691 +#: gtk/gtkentry.c:722 msgid "Scroll offset" msgstr "" -#: gtk/gtkentry.c:692 +#: gtk/gtkentry.c:723 msgid "Number of pixels of the entry scrolled off the screen to the left" msgstr "" -#: gtk/gtkentry.c:702 +#: gtk/gtkentry.c:733 msgid "The contents of the entry" msgstr "" -#: gtk/gtkentry.c:717 gtk/gtkmisc.c:73 +#: gtk/gtkentry.c:748 gtk/gtkmisc.c:73 msgid "X align" msgstr "" -#: gtk/gtkentry.c:718 gtk/gtkmisc.c:74 +#: gtk/gtkentry.c:749 gtk/gtkmisc.c:74 msgid "" "The horizontal alignment, from 0 (left) to 1 (right). Reversed for RTL " "layouts." msgstr "" -#: gtk/gtkentry.c:734 +#: gtk/gtkentry.c:765 msgid "Truncate multiline" msgstr "" -#: gtk/gtkentry.c:735 +#: gtk/gtkentry.c:766 msgid "Whether to truncate multiline pastes to one line." msgstr "" -#: gtk/gtkentry.c:751 +#: gtk/gtkentry.c:782 msgid "Which kind of shadow to draw around the entry when has-frame is set" msgstr "" -#: gtk/gtkentry.c:766 gtk/gtktextview.c:653 +#: gtk/gtkentry.c:797 gtk/gtktextview.c:654 msgid "Overwrite mode" msgstr "" -#: gtk/gtkentry.c:767 +#: gtk/gtkentry.c:798 msgid "Whether new text overwrites existing text" msgstr "" -#: gtk/gtkentry.c:781 +#: gtk/gtkentry.c:812 gtk/gtkentrybuffer.c:368 #, fuzzy msgid "Text length" msgstr "ዐምዶች" -#: gtk/gtkentry.c:782 +#: gtk/gtkentry.c:813 msgid "Length of the text currently in the entry" msgstr "" -#: gtk/gtkentry.c:797 +#: gtk/gtkentry.c:828 msgid "Invisible char set" msgstr "" -#: gtk/gtkentry.c:798 +#: gtk/gtkentry.c:829 msgid "Whether the invisible char has been set" msgstr "" -#: gtk/gtkentry.c:816 +#: gtk/gtkentry.c:847 msgid "Caps Lock warning" msgstr "" -#: gtk/gtkentry.c:817 +#: gtk/gtkentry.c:848 msgid "Whether password entries will show a warning when Caps Lock is on" msgstr "" -#: gtk/gtkentry.c:831 +#: gtk/gtkentry.c:862 msgid "Progress Fraction" msgstr "" -#: gtk/gtkentry.c:832 +#: gtk/gtkentry.c:863 #, fuzzy msgid "The current fraction of the task that's been completed" msgstr "የጽሑፉ መለያ" -#: gtk/gtkentry.c:849 +#: gtk/gtkentry.c:880 msgid "Progress Pulse Step" msgstr "" -#: gtk/gtkentry.c:850 +#: gtk/gtkentry.c:881 msgid "" "The fraction of total entry width to move the progress bouncing block for " "each call to gtk_entry_progress_pulse()" msgstr "" -#: gtk/gtkentry.c:866 +#: gtk/gtkentry.c:897 msgid "Primary pixbuf" msgstr "" -#: gtk/gtkentry.c:867 +#: gtk/gtkentry.c:898 msgid "Primary pixbuf for the entry" msgstr "" -#: gtk/gtkentry.c:881 +#: gtk/gtkentry.c:912 msgid "Secondary pixbuf" msgstr "" -#: gtk/gtkentry.c:882 +#: gtk/gtkentry.c:913 msgid "Secondary pixbuf for the entry" msgstr "" -#: gtk/gtkentry.c:896 +#: gtk/gtkentry.c:927 msgid "Primary stock ID" msgstr "" -#: gtk/gtkentry.c:897 +#: gtk/gtkentry.c:928 msgid "Stock ID for primary icon" msgstr "" -#: gtk/gtkentry.c:911 +#: gtk/gtkentry.c:942 msgid "Secondary stock ID" msgstr "" -#: gtk/gtkentry.c:912 +#: gtk/gtkentry.c:943 msgid "Stock ID for secondary icon" msgstr "" -#: gtk/gtkentry.c:926 -#, fuzzy -msgid "Primary icon name" -msgstr "የፊደሉ ቅርጽ ስም" - -#: gtk/gtkentry.c:927 -msgid "Icon name for primary icon" -msgstr "" - -#: gtk/gtkentry.c:941 -#, fuzzy -msgid "Secondary icon name" -msgstr "የመደቡ ቀለም ስም" - -#: gtk/gtkentry.c:942 -msgid "Icon name for secondary icon" -msgstr "" - -#: gtk/gtkentry.c:956 -msgid "Primary GIcon" -msgstr "" - #: gtk/gtkentry.c:957 #, fuzzy -msgid "GIcon for primary icon" -msgstr "ምልክት ለዚህን መስኮት" +msgid "Primary icon name" +msgstr "የፊደሉ ቅርጽ ስም" -#: gtk/gtkentry.c:971 -msgid "Secondary GIcon" +#: gtk/gtkentry.c:958 +msgid "Icon name for primary icon" msgstr "" #: gtk/gtkentry.c:972 +#, fuzzy +msgid "Secondary icon name" +msgstr "የመደቡ ቀለም ስም" + +#: gtk/gtkentry.c:973 +msgid "Icon name for secondary icon" +msgstr "" + +#: gtk/gtkentry.c:987 +msgid "Primary GIcon" +msgstr "" + +#: gtk/gtkentry.c:988 +#, fuzzy +msgid "GIcon for primary icon" +msgstr "ምልክት ለዚህን መስኮት" + +#: gtk/gtkentry.c:1002 +msgid "Secondary GIcon" +msgstr "" + +#: gtk/gtkentry.c:1003 msgid "GIcon for secondary icon" msgstr "" -#: gtk/gtkentry.c:986 +#: gtk/gtkentry.c:1017 #, fuzzy msgid "Primary storage type" msgstr "መጠን" -#: gtk/gtkentry.c:987 +#: gtk/gtkentry.c:1018 msgid "The representation being used for primary icon" msgstr "" -#: gtk/gtkentry.c:1002 +#: gtk/gtkentry.c:1033 msgid "Secondary storage type" msgstr "" -#: gtk/gtkentry.c:1003 +#: gtk/gtkentry.c:1034 msgid "The representation being used for secondary icon" msgstr "" -#: gtk/gtkentry.c:1024 +#: gtk/gtkentry.c:1055 msgid "Primary icon activatable" msgstr "" -#: gtk/gtkentry.c:1025 +#: gtk/gtkentry.c:1056 msgid "Whether the primary icon is activatable" msgstr "" -#: gtk/gtkentry.c:1045 +#: gtk/gtkentry.c:1076 msgid "Secondary icon activatable" msgstr "" -#: gtk/gtkentry.c:1046 +#: gtk/gtkentry.c:1077 msgid "Whether the secondary icon is activatable" msgstr "" -#: gtk/gtkentry.c:1068 +#: gtk/gtkentry.c:1099 msgid "Primary icon sensitive" msgstr "" -#: gtk/gtkentry.c:1069 +#: gtk/gtkentry.c:1100 msgid "Whether the primary icon is sensitive" msgstr "" -#: gtk/gtkentry.c:1090 +#: gtk/gtkentry.c:1121 msgid "Secondary icon sensitive" msgstr "" -#: gtk/gtkentry.c:1091 +#: gtk/gtkentry.c:1122 msgid "Whether the secondary icon is sensitive" msgstr "" -#: gtk/gtkentry.c:1107 +#: gtk/gtkentry.c:1138 #, fuzzy msgid "Primary icon tooltip text" msgstr "የፊደሉ ቅርጽ ስም" -#: gtk/gtkentry.c:1108 gtk/gtkentry.c:1144 +#: gtk/gtkentry.c:1139 gtk/gtkentry.c:1175 #, fuzzy msgid "The contents of the tooltip on the primary icon" msgstr "የመስኮቱ አርእስት" -#: gtk/gtkentry.c:1124 +#: gtk/gtkentry.c:1155 #, fuzzy msgid "Secondary icon tooltip text" msgstr "የመደቡ ቀለም ስም" -#: gtk/gtkentry.c:1125 gtk/gtkentry.c:1163 +#: gtk/gtkentry.c:1156 gtk/gtkentry.c:1194 #, fuzzy msgid "The contents of the tooltip on the secondary icon" msgstr "የመስኮቱ አርእስት" -#: gtk/gtkentry.c:1143 +#: gtk/gtkentry.c:1174 #, fuzzy msgid "Primary icon tooltip markup" msgstr "የፊደሉ ቅርጽ ስም" -#: gtk/gtkentry.c:1162 +#: gtk/gtkentry.c:1193 #, fuzzy msgid "Secondary icon tooltip markup" msgstr "የመደቡ ቀለም ስም" -#: gtk/gtkentry.c:1182 gtk/gtktextview.c:681 +#: gtk/gtkentry.c:1213 gtk/gtktextview.c:682 #, fuzzy msgid "IM module" msgstr "የነበረው ስፋት" -#: gtk/gtkentry.c:1183 gtk/gtktextview.c:682 +#: gtk/gtkentry.c:1214 gtk/gtktextview.c:683 msgid "Which IM module should be used" msgstr "" -#: gtk/gtkentry.c:1197 +#: gtk/gtkentry.c:1228 #, fuzzy msgid "Icon Prelight" msgstr "እርዝማኔ" -#: gtk/gtkentry.c:1198 +#: gtk/gtkentry.c:1229 msgid "Whether activatable icons should prelight when hovered" msgstr "" -#: gtk/gtkentry.c:1211 +#: gtk/gtkentry.c:1242 #, fuzzy msgid "Progress Border" msgstr "ቅደም ተከተል" -#: gtk/gtkentry.c:1212 +#: gtk/gtkentry.c:1243 #, fuzzy msgid "Border around the progress bar" msgstr "የጽሑፉ መለያ" -#: gtk/gtkentry.c:1683 +#: gtk/gtkentry.c:1714 msgid "Border between text and frame." msgstr "" -#: gtk/gtkentry.c:1697 +#: gtk/gtkentry.c:1728 msgid "State Hint" msgstr "" -#: gtk/gtkentry.c:1698 +#: gtk/gtkentry.c:1729 msgid "Whether to pass a proper state when drawing shadow or background" msgstr "" -#: gtk/gtkentry.c:1703 gtk/gtklabel.c:830 +#: gtk/gtkentry.c:1734 gtk/gtklabel.c:848 msgid "Select on focus" msgstr "" -#: gtk/gtkentry.c:1704 +#: gtk/gtkentry.c:1735 msgid "Whether to select the contents of an entry when it is focused" msgstr "" -#: gtk/gtkentry.c:1718 +#: gtk/gtkentry.c:1749 msgid "Password Hint Timeout" msgstr "" -#: gtk/gtkentry.c:1719 +#: gtk/gtkentry.c:1750 msgid "How long to show the last input character in hidden entries" msgstr "" +#: gtk/gtkentrybuffer.c:354 +#, fuzzy +msgid "The contents of the buffer" +msgstr "የጽሑፉ መለያ" + +#: gtk/gtkentrybuffer.c:369 +msgid "Length of the text currently in the buffer" +msgstr "" + #: gtk/gtkentrycompletion.c:279 msgid "Completion Model" msgstr "" @@ -2496,7 +2544,7 @@ msgstr "" msgid "Minimum length of the search key in order to look up matches" msgstr "" -#: gtk/gtkentrycompletion.c:303 gtk/gtkiconview.c:585 +#: gtk/gtkentrycompletion.c:303 gtk/gtkiconview.c:586 #, fuzzy msgid "Text column" msgstr "ዐምዶች" @@ -2579,11 +2627,11 @@ msgstr "" msgid "Text of the expander's label" msgstr "የጽሑፉ መለያ" -#: gtk/gtkexpander.c:211 gtk/gtklabel.c:509 +#: gtk/gtkexpander.c:211 gtk/gtklabel.c:510 msgid "Use markup" msgstr "" -#: gtk/gtkexpander.c:212 gtk/gtklabel.c:510 +#: gtk/gtkexpander.c:212 gtk/gtklabel.c:511 msgid "The text of the label includes XML markup. See pango_parse_markup()" msgstr "" @@ -2599,11 +2647,11 @@ msgstr "" msgid "A widget to display in place of the usual expander label" msgstr "" -#: gtk/gtkexpander.c:236 gtk/gtktreeview.c:783 +#: gtk/gtkexpander.c:236 gtk/gtktreeview.c:774 msgid "Expander Size" msgstr "" -#: gtk/gtkexpander.c:237 gtk/gtktreeview.c:784 +#: gtk/gtkexpander.c:237 gtk/gtktreeview.c:775 msgid "Size of the expander arrow" msgstr "" @@ -2711,6 +2759,16 @@ msgid "" "dialog if necessary." msgstr "" +#: gtk/gtkfilechooser.c:283 +msgid "Allow folders creation" +msgstr "" + +#: gtk/gtkfilechooser.c:284 +msgid "" +"Whether a file chooser not in open mode will offer the user to create new " +"folders." +msgstr "" + #: gtk/gtkfilechooserbutton.c:376 msgid "Dialog" msgstr "" @@ -2729,7 +2787,7 @@ msgid "The desired width of the button widget, in characters." msgstr "" #: gtk/gtkfilesel.c:526 gtk/gtkimage.c:163 gtk/gtkrecentmanager.c:214 -#: gtk/gtkstatusicon.c:218 +#: gtk/gtkstatusicon.c:221 msgid "Filename" msgstr "የፋይል ስም" @@ -2907,90 +2965,90 @@ msgid "" "detached." msgstr "" -#: gtk/gtkiconview.c:548 +#: gtk/gtkiconview.c:549 msgid "Selection mode" msgstr "" -#: gtk/gtkiconview.c:549 +#: gtk/gtkiconview.c:550 msgid "The selection mode" msgstr "" -#: gtk/gtkiconview.c:567 +#: gtk/gtkiconview.c:568 #, fuzzy msgid "Pixbuf column" msgstr "ዐምዶች" -#: gtk/gtkiconview.c:568 +#: gtk/gtkiconview.c:569 msgid "Model column used to retrieve the icon pixbuf from" msgstr "" -#: gtk/gtkiconview.c:586 +#: gtk/gtkiconview.c:587 msgid "Model column used to retrieve the text from" msgstr "" -#: gtk/gtkiconview.c:605 +#: gtk/gtkiconview.c:606 msgid "Markup column" msgstr "" -#: gtk/gtkiconview.c:606 +#: gtk/gtkiconview.c:607 msgid "Model column used to retrieve the text if using Pango markup" msgstr "" -#: gtk/gtkiconview.c:613 +#: gtk/gtkiconview.c:614 #, fuzzy msgid "Icon View Model" msgstr "የምልክት መጠን" -#: gtk/gtkiconview.c:614 +#: gtk/gtkiconview.c:615 #, fuzzy msgid "The model for the icon view" msgstr "የመስኮቱ ዓይነት" -#: gtk/gtkiconview.c:630 +#: gtk/gtkiconview.c:631 #, fuzzy msgid "Number of columns" msgstr "ዐምዶች" -#: gtk/gtkiconview.c:631 +#: gtk/gtkiconview.c:632 msgid "Number of columns to display" msgstr "" -#: gtk/gtkiconview.c:648 +#: gtk/gtkiconview.c:649 msgid "Width for each item" msgstr "" -#: gtk/gtkiconview.c:649 +#: gtk/gtkiconview.c:650 msgid "The width used for each item" msgstr "" -#: gtk/gtkiconview.c:665 +#: gtk/gtkiconview.c:666 msgid "Space which is inserted between cells of an item" msgstr "" -#: gtk/gtkiconview.c:680 +#: gtk/gtkiconview.c:681 #, fuzzy msgid "Row Spacing" msgstr "ክፍተት" -#: gtk/gtkiconview.c:681 +#: gtk/gtkiconview.c:682 msgid "Space which is inserted between grid rows" msgstr "" -#: gtk/gtkiconview.c:696 +#: gtk/gtkiconview.c:697 #, fuzzy msgid "Column Spacing" msgstr "ክፍተት" -#: gtk/gtkiconview.c:697 +#: gtk/gtkiconview.c:698 msgid "Space which is inserted between grid columns" msgstr "" -#: gtk/gtkiconview.c:712 +#: gtk/gtkiconview.c:713 #, fuzzy msgid "Margin" msgstr "የግራ ህዳግ" -#: gtk/gtkiconview.c:713 +#: gtk/gtkiconview.c:714 msgid "Space which is inserted at the edges of the icon view" msgstr "" @@ -2999,15 +3057,15 @@ msgid "" "How the text and icon of each item are positioned relative to each other" msgstr "" -#: gtk/gtkiconview.c:746 gtk/gtktreeview.c:618 gtk/gtktreeviewcolumn.c:307 +#: gtk/gtkiconview.c:746 gtk/gtktreeview.c:609 gtk/gtktreeviewcolumn.c:308 msgid "Reorderable" msgstr "" -#: gtk/gtkiconview.c:747 gtk/gtktreeview.c:619 +#: gtk/gtkiconview.c:747 gtk/gtktreeview.c:610 msgid "View is reorderable" msgstr "" -#: gtk/gtkiconview.c:754 gtk/gtktreeview.c:769 +#: gtk/gtkiconview.c:754 gtk/gtktreeview.c:760 #, fuzzy msgid "Tooltip Column" msgstr "ዐምዶች" @@ -3016,29 +3074,38 @@ msgstr "ዐምዶች" msgid "The column in the model containing the tooltip texts for the items" msgstr "" -#: gtk/gtkiconview.c:766 +#: gtk/gtkiconview.c:772 +#, fuzzy +msgid "Item Padding" +msgstr "የግራ ህዳግ" + +#: gtk/gtkiconview.c:773 +msgid "Padding around icon view items" +msgstr "" + +#: gtk/gtkiconview.c:782 msgid "Selection Box Color" msgstr "" -#: gtk/gtkiconview.c:767 +#: gtk/gtkiconview.c:783 #, fuzzy msgid "Color of the selection box" msgstr "የመስኮቱ አርእስት" -#: gtk/gtkiconview.c:773 +#: gtk/gtkiconview.c:789 msgid "Selection Box Alpha" msgstr "" -#: gtk/gtkiconview.c:774 +#: gtk/gtkiconview.c:790 #, fuzzy msgid "Opacity of the selection box" msgstr "የመስኮቱ አርእስት" -#: gtk/gtkimage.c:131 gtk/gtkstatusicon.c:210 +#: gtk/gtkimage.c:131 gtk/gtkstatusicon.c:213 msgid "Pixbuf" msgstr "" -#: gtk/gtkimage.c:132 gtk/gtkstatusicon.c:211 +#: gtk/gtkimage.c:132 gtk/gtkstatusicon.c:214 msgid "A GdkPixbuf to display" msgstr "" @@ -3066,11 +3133,11 @@ msgstr "" msgid "Mask bitmap to use with GdkImage or GdkPixmap" msgstr "" -#: gtk/gtkimage.c:164 gtk/gtkstatusicon.c:219 +#: gtk/gtkimage.c:164 gtk/gtkstatusicon.c:222 msgid "Filename to load and display" msgstr "" -#: gtk/gtkimage.c:173 gtk/gtkstatusicon.c:227 +#: gtk/gtkimage.c:173 gtk/gtkstatusicon.c:230 msgid "Stock ID for a stock image to display" msgstr "" @@ -3107,11 +3174,11 @@ msgstr "" msgid "GdkPixbufAnimation to display" msgstr "" -#: gtk/gtkimage.c:255 gtk/gtkstatusicon.c:258 +#: gtk/gtkimage.c:255 gtk/gtkstatusicon.c:261 msgid "Storage type" msgstr "" -#: gtk/gtkimage.c:256 gtk/gtkstatusicon.c:259 +#: gtk/gtkimage.c:256 gtk/gtkstatusicon.c:262 msgid "The representation being used for image data" msgstr "" @@ -3131,7 +3198,7 @@ msgstr "" msgid "Whether the image will always be shown" msgstr "" -#: gtk/gtkimagemenuitem.c:184 gtk/gtkmenu.c:515 +#: gtk/gtkimagemenuitem.c:184 gtk/gtkmenu.c:516 #, fuzzy msgid "Accel Group" msgstr "ምልክት" @@ -3149,111 +3216,142 @@ msgstr "ማስረጊያዎች አሳይ" msgid "Whether images should be shown in menus" msgstr "" +#: gtk/gtkinfobar.c:384 gtk/gtkmessagedialog.c:128 +msgid "Message Type" +msgstr "" + +#: gtk/gtkinfobar.c:385 gtk/gtkmessagedialog.c:129 +msgid "The type of message" +msgstr "" + +#: gtk/gtkinfobar.c:440 +#, fuzzy +msgid "Width of border around the content area" +msgstr "የጽሑፉ መለያ" + +#: gtk/gtkinfobar.c:457 +msgid "Spacing between elements of the area" +msgstr "" + +#: gtk/gtkinfobar.c:489 +#, fuzzy +msgid "Width of border around the action area" +msgstr "የጽሑፉ መለያ" + #: gtk/gtkinvisible.c:87 gtk/gtkwindow.c:615 msgid "The screen where this window will be displayed" msgstr "" -#: gtk/gtklabel.c:496 +#: gtk/gtklabel.c:497 msgid "The text of the label" msgstr "የጽሑፉ መለያ" -#: gtk/gtklabel.c:503 +#: gtk/gtklabel.c:504 msgid "A list of style attributes to apply to the text of the label" msgstr "" -#: gtk/gtklabel.c:524 gtk/gtktexttag.c:359 gtk/gtktextview.c:590 +#: gtk/gtklabel.c:525 gtk/gtktexttag.c:359 gtk/gtktextview.c:591 msgid "Justification" msgstr "" -#: gtk/gtklabel.c:525 +#: gtk/gtklabel.c:526 msgid "" "The alignment of the lines in the text of the label relative to each other. " "This does NOT affect the alignment of the label within its allocation. See " "GtkMisc::xalign for that" msgstr "" -#: gtk/gtklabel.c:533 +#: gtk/gtklabel.c:534 msgid "Pattern" msgstr "ንድፍ" -#: gtk/gtklabel.c:534 +#: gtk/gtklabel.c:535 msgid "" "A string with _ characters in positions correspond to characters in the text " "to underline" msgstr "" -#: gtk/gtklabel.c:541 +#: gtk/gtklabel.c:542 msgid "Line wrap" msgstr "" -#: gtk/gtklabel.c:542 +#: gtk/gtklabel.c:543 msgid "If set, wrap lines if the text becomes too wide" msgstr "" -#: gtk/gtklabel.c:557 +#: gtk/gtklabel.c:558 #, fuzzy msgid "Line wrap mode" msgstr "የመሸፈኛ ዘዴ" -#: gtk/gtklabel.c:558 +#: gtk/gtklabel.c:559 msgid "If wrap is set, controls how linewrapping is done" msgstr "" -#: gtk/gtklabel.c:565 +#: gtk/gtklabel.c:566 msgid "Selectable" msgstr "" -#: gtk/gtklabel.c:566 +#: gtk/gtklabel.c:567 msgid "Whether the label text can be selected with the mouse" msgstr "" -#: gtk/gtklabel.c:572 +#: gtk/gtklabel.c:573 msgid "Mnemonic key" msgstr "" -#: gtk/gtklabel.c:573 +#: gtk/gtklabel.c:574 msgid "The mnemonic accelerator key for this label" msgstr "" -#: gtk/gtklabel.c:581 +#: gtk/gtklabel.c:582 msgid "Mnemonic widget" msgstr "" -#: gtk/gtklabel.c:582 +#: gtk/gtklabel.c:583 msgid "The widget to be activated when the label's mnemonic key is pressed" msgstr "" -#: gtk/gtklabel.c:628 +#: gtk/gtklabel.c:629 msgid "" "The preferred place to ellipsize the string, if the label does not have " "enough room to display the entire string" msgstr "" -#: gtk/gtklabel.c:668 +#: gtk/gtklabel.c:669 msgid "Single Line Mode" msgstr "" -#: gtk/gtklabel.c:669 +#: gtk/gtklabel.c:670 msgid "Whether the label is in single line mode" msgstr "" -#: gtk/gtklabel.c:686 +#: gtk/gtklabel.c:687 msgid "Angle" msgstr "" -#: gtk/gtklabel.c:687 +#: gtk/gtklabel.c:688 msgid "Angle at which the label is rotated" msgstr "" -#: gtk/gtklabel.c:707 +#: gtk/gtklabel.c:708 msgid "Maximum Width In Characters" msgstr "" -#: gtk/gtklabel.c:708 +#: gtk/gtklabel.c:709 msgid "The desired maximum width of the label, in characters" msgstr "" -#: gtk/gtklabel.c:831 +#: gtk/gtklabel.c:727 +#, fuzzy +msgid "Track visited links" +msgstr "የመስኮቱ አርእስት" + +#: gtk/gtklabel.c:728 +msgid "Whether visited links should be tracked" +msgstr "" + +#: gtk/gtklabel.c:849 msgid "Whether to select the contents of a selectable label when it is focused" msgstr "" @@ -3298,172 +3396,182 @@ msgstr "የሚታይ" msgid "Whether this link has been visited." msgstr "" -#: gtk/gtkmenu.c:501 +#: gtk/gtkmenu.c:502 #, fuzzy msgid "The currently selected menu item" msgstr "የጽሑፉ መለያ" -#: gtk/gtkmenu.c:516 +#: gtk/gtkmenu.c:517 msgid "The accel group holding accelerators for the menu" msgstr "" -#: gtk/gtkmenu.c:530 gtk/gtkmenuitem.c:285 +#: gtk/gtkmenu.c:531 gtk/gtkmenuitem.c:290 msgid "Accel Path" msgstr "" -#: gtk/gtkmenu.c:531 +#: gtk/gtkmenu.c:532 msgid "An accel path used to conveniently construct accel paths of child items" msgstr "" -#: gtk/gtkmenu.c:547 +#: gtk/gtkmenu.c:548 #, fuzzy msgid "Attach Widget" msgstr "ስፋት" -#: gtk/gtkmenu.c:548 +#: gtk/gtkmenu.c:549 msgid "The widget the menu is attached to" msgstr "" -#: gtk/gtkmenu.c:556 +#: gtk/gtkmenu.c:557 msgid "" "A title that may be displayed by the window manager when this menu is torn-" "off" msgstr "" -#: gtk/gtkmenu.c:570 +#: gtk/gtkmenu.c:571 msgid "Tearoff State" msgstr "" -#: gtk/gtkmenu.c:571 +#: gtk/gtkmenu.c:572 msgid "A boolean that indicates whether the menu is torn-off" msgstr "" -#: gtk/gtkmenu.c:585 +#: gtk/gtkmenu.c:586 #, fuzzy msgid "Monitor" msgstr "የፊደል ቅርጽ" -#: gtk/gtkmenu.c:586 +#: gtk/gtkmenu.c:587 msgid "The monitor the menu will be popped up on" msgstr "" -#: gtk/gtkmenu.c:592 +#: gtk/gtkmenu.c:593 #, fuzzy msgid "Vertical Padding" msgstr "የቁመት ኩልኩል" -#: gtk/gtkmenu.c:593 +#: gtk/gtkmenu.c:594 msgid "Extra space at the top and bottom of the menu" msgstr "" -#: gtk/gtkmenu.c:601 +#: gtk/gtkmenu.c:616 +msgid "Reserve Toggle Size" +msgstr "" + +#: gtk/gtkmenu.c:617 +msgid "" +"A boolean that indicates whether the menu reserves space for toggles and " +"icons" +msgstr "" + +#: gtk/gtkmenu.c:623 #, fuzzy msgid "Horizontal Padding" msgstr "የአግድም ኩልኩል" -#: gtk/gtkmenu.c:602 +#: gtk/gtkmenu.c:624 msgid "Extra space at the left and right edges of the menu" msgstr "" -#: gtk/gtkmenu.c:610 +#: gtk/gtkmenu.c:632 #, fuzzy msgid "Vertical Offset" msgstr "የቁመት ኩልኩል" -#: gtk/gtkmenu.c:611 +#: gtk/gtkmenu.c:633 msgid "" "When the menu is a submenu, position it this number of pixels offset " "vertically" msgstr "" -#: gtk/gtkmenu.c:619 +#: gtk/gtkmenu.c:641 #, fuzzy msgid "Horizontal Offset" msgstr "የአግድም ኩልኩል" -#: gtk/gtkmenu.c:620 +#: gtk/gtkmenu.c:642 msgid "" "When the menu is a submenu, position it this number of pixels offset " "horizontally" msgstr "" -#: gtk/gtkmenu.c:628 +#: gtk/gtkmenu.c:650 msgid "Double Arrows" msgstr "" -#: gtk/gtkmenu.c:629 +#: gtk/gtkmenu.c:651 msgid "When scrolling, always show both arrows." msgstr "" -#: gtk/gtkmenu.c:642 +#: gtk/gtkmenu.c:664 #, fuzzy msgid "Arrow Placement" msgstr "ክፍተት" -#: gtk/gtkmenu.c:643 +#: gtk/gtkmenu.c:665 msgid "Indicates where scroll arrows should be placed" msgstr "" -#: gtk/gtkmenu.c:651 +#: gtk/gtkmenu.c:673 msgid "Left Attach" msgstr "" -#: gtk/gtkmenu.c:652 gtk/gtktable.c:174 +#: gtk/gtkmenu.c:674 gtk/gtktable.c:174 msgid "The column number to attach the left side of the child to" msgstr "" -#: gtk/gtkmenu.c:659 +#: gtk/gtkmenu.c:681 msgid "Right Attach" msgstr "" -#: gtk/gtkmenu.c:660 +#: gtk/gtkmenu.c:682 msgid "The column number to attach the right side of the child to" msgstr "" -#: gtk/gtkmenu.c:667 +#: gtk/gtkmenu.c:689 msgid "Top Attach" msgstr "" -#: gtk/gtkmenu.c:668 +#: gtk/gtkmenu.c:690 msgid "The row number to attach the top of the child to" msgstr "" -#: gtk/gtkmenu.c:675 +#: gtk/gtkmenu.c:697 #, fuzzy msgid "Bottom Attach" msgstr "ወደ ታች (_B)" -#: gtk/gtkmenu.c:676 gtk/gtktable.c:195 +#: gtk/gtkmenu.c:698 gtk/gtktable.c:195 msgid "The row number to attach the bottom of the child to" msgstr "" -#: gtk/gtkmenu.c:690 +#: gtk/gtkmenu.c:712 msgid "Arbitrary constant to scale down the size of the scroll arrow" msgstr "" -#: gtk/gtkmenu.c:777 +#: gtk/gtkmenu.c:799 msgid "Can change accelerators" msgstr "" -#: gtk/gtkmenu.c:778 +#: gtk/gtkmenu.c:800 msgid "" "Whether menu accelerators can be changed by pressing a key over the menu item" msgstr "" -#: gtk/gtkmenu.c:783 +#: gtk/gtkmenu.c:805 msgid "Delay before submenus appear" msgstr "" -#: gtk/gtkmenu.c:784 +#: gtk/gtkmenu.c:806 msgid "" "Minimum time the pointer must stay over a menu item before the submenu appear" msgstr "" -#: gtk/gtkmenu.c:791 +#: gtk/gtkmenu.c:813 msgid "Delay before hiding a submenu" msgstr "" -#: gtk/gtkmenu.c:792 +#: gtk/gtkmenu.c:814 msgid "" "The time before hiding a submenu when the pointer is moving towards the " "submenu" @@ -3507,41 +3615,41 @@ msgstr "" msgid "Delay before the submenus of a menu bar appear" msgstr "" -#: gtk/gtkmenuitem.c:252 +#: gtk/gtkmenuitem.c:257 msgid "Right Justified" msgstr "" -#: gtk/gtkmenuitem.c:253 +#: gtk/gtkmenuitem.c:258 msgid "" "Sets whether the menu item appears justified at the right side of a menu bar" msgstr "" -#: gtk/gtkmenuitem.c:267 +#: gtk/gtkmenuitem.c:272 msgid "Submenu" msgstr "" -#: gtk/gtkmenuitem.c:268 +#: gtk/gtkmenuitem.c:273 msgid "The submenu attached to the menu item, or NULL if it has none" msgstr "" -#: gtk/gtkmenuitem.c:286 +#: gtk/gtkmenuitem.c:291 msgid "Sets the accelerator path of the menu item" msgstr "" -#: gtk/gtkmenuitem.c:301 +#: gtk/gtkmenuitem.c:306 #, fuzzy msgid "The text for the child label" msgstr "የጽሑፉ መለያ" -#: gtk/gtkmenuitem.c:364 +#: gtk/gtkmenuitem.c:369 msgid "Amount of space used up by arrow, relative to the menu item's font size" msgstr "" -#: gtk/gtkmenuitem.c:377 +#: gtk/gtkmenuitem.c:382 msgid "Width in Characters" msgstr "" -#: gtk/gtkmenuitem.c:378 +#: gtk/gtkmenuitem.c:383 msgid "The minimum desired width of the menu item in characters" msgstr "" @@ -3578,14 +3686,6 @@ msgid "" "Whether to put a separator between the message dialog's text and the buttons" msgstr "" -#: gtk/gtkmessagedialog.c:128 -msgid "Message Type" -msgstr "" - -#: gtk/gtkmessagedialog.c:129 -msgid "The type of message" -msgstr "" - #: gtk/gtkmessagedialog.c:136 msgid "Message Buttons" msgstr "" @@ -3655,25 +3755,25 @@ msgid "" "The amount of space to add on the top and bottom of the widget, in pixels" msgstr "" -#: gtk/gtkmountoperation.c:139 +#: gtk/gtkmountoperation.c:160 #, fuzzy msgid "Parent" msgstr "ንድፍ" -#: gtk/gtkmountoperation.c:140 +#: gtk/gtkmountoperation.c:161 #, fuzzy msgid "The parent window" msgstr "የመስኮቱ ዓይነት" -#: gtk/gtkmountoperation.c:147 +#: gtk/gtkmountoperation.c:168 msgid "Is Showing" msgstr "" -#: gtk/gtkmountoperation.c:148 +#: gtk/gtkmountoperation.c:169 msgid "Are we showing a dialog" msgstr "" -#: gtk/gtkmountoperation.c:156 +#: gtk/gtkmountoperation.c:177 msgid "The screen where this window will be displayed." msgstr "" @@ -3966,7 +4066,7 @@ msgstr "" msgid "If TRUE, the child can be made smaller than its requisition" msgstr "" -#: gtk/gtkplug.c:150 gtk/gtkstatusicon.c:309 +#: gtk/gtkplug.c:150 gtk/gtkstatusicon.c:312 msgid "Embedded" msgstr "" @@ -4102,12 +4202,12 @@ msgstr "" msgid "Printer settings" msgstr "" -#: gtk/gtkprintjob.c:143 gtk/gtkprintjob.c:144 gtk/gtkprintunixdialog.c:266 +#: gtk/gtkprintjob.c:143 gtk/gtkprintjob.c:144 gtk/gtkprintunixdialog.c:302 #, fuzzy msgid "Page Setup" msgstr "መጠን" -#: gtk/gtkprintjob.c:152 gtk/gtkprintoperation.c:1056 +#: gtk/gtkprintjob.c:152 gtk/gtkprintoperation.c:1082 msgid "Track Print Status" msgstr "" @@ -4117,169 +4217,192 @@ msgid "" "print data has been sent to the printer or print server." msgstr "" -#: gtk/gtkprintoperation.c:928 +#: gtk/gtkprintoperation.c:954 #, fuzzy msgid "Default Page Setup" msgstr "የነበረው እርዝማኔ" -#: gtk/gtkprintoperation.c:929 +#: gtk/gtkprintoperation.c:955 msgid "The GtkPageSetup used by default" msgstr "" -#: gtk/gtkprintoperation.c:947 gtk/gtkprintunixdialog.c:284 +#: gtk/gtkprintoperation.c:973 gtk/gtkprintunixdialog.c:320 msgid "Print Settings" msgstr "" -#: gtk/gtkprintoperation.c:948 gtk/gtkprintunixdialog.c:285 +#: gtk/gtkprintoperation.c:974 gtk/gtkprintunixdialog.c:321 msgid "The GtkPrintSettings used for initializing the dialog" msgstr "" -#: gtk/gtkprintoperation.c:966 +#: gtk/gtkprintoperation.c:992 #, fuzzy msgid "Job Name" msgstr "የፊደሉ ቅርጽ ስም" -#: gtk/gtkprintoperation.c:967 +#: gtk/gtkprintoperation.c:993 msgid "A string used for identifying the print job." msgstr "" -#: gtk/gtkprintoperation.c:991 +#: gtk/gtkprintoperation.c:1017 #, fuzzy msgid "Number of Pages" msgstr "ዐምዶች" -#: gtk/gtkprintoperation.c:992 +#: gtk/gtkprintoperation.c:1018 #, fuzzy msgid "The number of pages in the document." msgstr "የጽሑፉ መለያ" -#: gtk/gtkprintoperation.c:1013 gtk/gtkprintunixdialog.c:274 +#: gtk/gtkprintoperation.c:1039 gtk/gtkprintunixdialog.c:310 #, fuzzy msgid "Current Page" msgstr "የአሁኑን ቀለም" -#: gtk/gtkprintoperation.c:1014 gtk/gtkprintunixdialog.c:275 +#: gtk/gtkprintoperation.c:1040 gtk/gtkprintunixdialog.c:311 #, fuzzy msgid "The current page in the document" msgstr "የጽሑፉ መለያ" -#: gtk/gtkprintoperation.c:1035 +#: gtk/gtkprintoperation.c:1061 msgid "Use full page" msgstr "" -#: gtk/gtkprintoperation.c:1036 +#: gtk/gtkprintoperation.c:1062 msgid "" "TRUE if the origin of the context should be at the corner of the page and " "not the corner of the imageable area" msgstr "" -#: gtk/gtkprintoperation.c:1057 +#: gtk/gtkprintoperation.c:1083 msgid "" "TRUE if the print operation will continue to report on the print job status " "after the print data has been sent to the printer or print server." msgstr "" -#: gtk/gtkprintoperation.c:1074 +#: gtk/gtkprintoperation.c:1100 msgid "Unit" msgstr "" -#: gtk/gtkprintoperation.c:1075 +#: gtk/gtkprintoperation.c:1101 msgid "The unit in which distances can be measured in the context" msgstr "" -#: gtk/gtkprintoperation.c:1092 +#: gtk/gtkprintoperation.c:1118 #, fuzzy msgid "Show Dialog" msgstr "ማስረጊያዎች አሳይ" -#: gtk/gtkprintoperation.c:1093 +#: gtk/gtkprintoperation.c:1119 msgid "TRUE if a progress dialog is shown while printing." msgstr "" -#: gtk/gtkprintoperation.c:1116 +#: gtk/gtkprintoperation.c:1142 msgid "Allow Async" msgstr "" -#: gtk/gtkprintoperation.c:1117 +#: gtk/gtkprintoperation.c:1143 msgid "TRUE if print process may run asynchronous." msgstr "" -#: gtk/gtkprintoperation.c:1139 gtk/gtkprintoperation.c:1140 +#: gtk/gtkprintoperation.c:1165 gtk/gtkprintoperation.c:1166 #, fuzzy msgid "Export filename" msgstr "የፋይል ስም" -#: gtk/gtkprintoperation.c:1154 +#: gtk/gtkprintoperation.c:1180 msgid "Status" msgstr "" -#: gtk/gtkprintoperation.c:1155 +#: gtk/gtkprintoperation.c:1181 #, fuzzy msgid "The status of the print operation" msgstr "የመስኮቱ አርእስት" -#: gtk/gtkprintoperation.c:1175 +#: gtk/gtkprintoperation.c:1201 msgid "Status String" msgstr "" -#: gtk/gtkprintoperation.c:1176 +#: gtk/gtkprintoperation.c:1202 msgid "A human-readable description of the status" msgstr "" -#: gtk/gtkprintoperation.c:1194 +#: gtk/gtkprintoperation.c:1220 msgid "Custom tab label" msgstr "" -#: gtk/gtkprintoperation.c:1195 +#: gtk/gtkprintoperation.c:1221 msgid "Label for the tab containing custom widgets." msgstr "" -#: gtk/gtkprintoperation.c:1210 gtk/gtkprintunixdialog.c:309 +#: gtk/gtkprintoperation.c:1236 gtk/gtkprintunixdialog.c:345 #, fuzzy msgid "Support Selection" msgstr "የመስኮቱ አርእስት" -#: gtk/gtkprintoperation.c:1211 +#: gtk/gtkprintoperation.c:1237 msgid "TRUE if the print operation will support print of selection." msgstr "" -#: gtk/gtkprintoperation.c:1227 gtk/gtkprintunixdialog.c:317 +#: gtk/gtkprintoperation.c:1253 gtk/gtkprintunixdialog.c:353 #, fuzzy msgid "Has Selection" msgstr "የመስኮቱ አርእስት" -#: gtk/gtkprintoperation.c:1228 +#: gtk/gtkprintoperation.c:1254 msgid "TRUE if a selecion exists." msgstr "" -#: gtk/gtkprintunixdialog.c:267 +#: gtk/gtkprintoperation.c:1269 gtk/gtkprintunixdialog.c:361 +#, fuzzy +msgid "Embed Page Setup" +msgstr "መጠን" + +#: gtk/gtkprintoperation.c:1270 +msgid "TRUE if page setup combos are embedded in GtkPrintDialog" +msgstr "" + +#: gtk/gtkprintoperation.c:1291 +#, fuzzy +msgid "Number of Pages To Print" +msgstr "ዐምዶች" + +#: gtk/gtkprintoperation.c:1292 +#, fuzzy +msgid "The number of pages that will be printed." +msgstr "የጽሑፉ መለያ" + +#: gtk/gtkprintunixdialog.c:303 msgid "The GtkPageSetup to use" msgstr "" -#: gtk/gtkprintunixdialog.c:292 +#: gtk/gtkprintunixdialog.c:328 msgid "Selected Printer" msgstr "" -#: gtk/gtkprintunixdialog.c:293 +#: gtk/gtkprintunixdialog.c:329 msgid "The GtkPrinter which is selected" msgstr "" -#: gtk/gtkprintunixdialog.c:300 +#: gtk/gtkprintunixdialog.c:336 msgid "Manual Capabilites" msgstr "" -#: gtk/gtkprintunixdialog.c:301 +#: gtk/gtkprintunixdialog.c:337 msgid "Capabilities the application can handle" msgstr "" -#: gtk/gtkprintunixdialog.c:310 +#: gtk/gtkprintunixdialog.c:346 msgid "Whether the dialog supports selection" msgstr "" -#: gtk/gtkprintunixdialog.c:318 +#: gtk/gtkprintunixdialog.c:354 msgid "Whether the application has a selection" msgstr "" +#: gtk/gtkprintunixdialog.c:362 +msgid "TRUE if page setup combos are embedded in GtkPrintUnixDialog" +msgstr "" + #: gtk/gtkprogress.c:102 msgid "Activity mode" msgstr "" @@ -4835,11 +4958,11 @@ msgid "" "Display a second forward arrow button on the opposite end of the scrollbar" msgstr "" -#: gtk/gtkscrolledwindow.c:218 gtk/gtktext.c:545 gtk/gtktreeview.c:578 +#: gtk/gtkscrolledwindow.c:218 gtk/gtktext.c:545 gtk/gtktreeview.c:569 msgid "Horizontal Adjustment" msgstr "" -#: gtk/gtkscrolledwindow.c:225 gtk/gtktext.c:553 gtk/gtktreeview.c:586 +#: gtk/gtkscrolledwindow.c:225 gtk/gtktext.c:553 gtk/gtktreeview.c:577 msgid "Vertical Adjustment" msgstr "" @@ -5367,21 +5490,21 @@ msgstr "ማስረጊያዎች አሳይ" msgid "Whether tooltips should be shown on widgets" msgstr "" -#: gtk/gtksizegroup.c:293 +#: gtk/gtksizegroup.c:301 msgid "Mode" msgstr "የአሠራሩ ዘዴ" -#: gtk/gtksizegroup.c:294 +#: gtk/gtksizegroup.c:302 msgid "" "The directions in which the size group affects the requested sizes of its " "component widgets" msgstr "" -#: gtk/gtksizegroup.c:310 +#: gtk/gtksizegroup.c:318 msgid "Ignore hidden" msgstr "" -#: gtk/gtksizegroup.c:311 +#: gtk/gtksizegroup.c:319 msgid "" "If TRUE, unmapped widgets are ignored when determining the size of the group" msgstr "" @@ -5449,61 +5572,66 @@ msgstr "" msgid "Style of bevel around the statusbar text" msgstr "" -#: gtk/gtkstatusicon.c:268 +#: gtk/gtkstatusicon.c:271 #, fuzzy msgid "The size of the icon" msgstr "የመስኮቱ አርእስት" -#: gtk/gtkstatusicon.c:278 +#: gtk/gtkstatusicon.c:281 msgid "The screen where this status icon will be displayed" msgstr "" -#: gtk/gtkstatusicon.c:285 +#: gtk/gtkstatusicon.c:288 msgid "Blinking" msgstr "" -#: gtk/gtkstatusicon.c:286 +#: gtk/gtkstatusicon.c:289 msgid "Whether or not the status icon is blinking" msgstr "" -#: gtk/gtkstatusicon.c:294 +#: gtk/gtkstatusicon.c:297 msgid "Whether or not the status icon is visible" msgstr "" -#: gtk/gtkstatusicon.c:310 +#: gtk/gtkstatusicon.c:313 msgid "Whether or not the status icon is embedded" msgstr "" -#: gtk/gtkstatusicon.c:326 gtk/gtktrayicon-x11.c:111 +#: gtk/gtkstatusicon.c:329 gtk/gtktrayicon-x11.c:111 #, fuzzy msgid "The orientation of the tray" msgstr "የጽሑፉ መለያ" -#: gtk/gtkstatusicon.c:353 gtk/gtkwidget.c:632 +#: gtk/gtkstatusicon.c:356 gtk/gtkwidget.c:634 msgid "Has tooltip" msgstr "" -#: gtk/gtkstatusicon.c:354 +#: gtk/gtkstatusicon.c:357 msgid "Whether this tray icon has a tooltip" msgstr "" -#: gtk/gtkstatusicon.c:375 gtk/gtkwidget.c:653 +#: gtk/gtkstatusicon.c:382 gtk/gtkwidget.c:655 msgid "Tooltip Text" msgstr "" -#: gtk/gtkstatusicon.c:376 gtk/gtkwidget.c:654 gtk/gtkwidget.c:675 +#: gtk/gtkstatusicon.c:383 gtk/gtkwidget.c:656 gtk/gtkwidget.c:677 msgid "The contents of the tooltip for this widget" msgstr "" -#: gtk/gtkstatusicon.c:399 gtk/gtkwidget.c:674 +#: gtk/gtkstatusicon.c:406 gtk/gtkwidget.c:676 msgid "Tooltip markup" msgstr "" -#: gtk/gtkstatusicon.c:400 +#: gtk/gtkstatusicon.c:407 #, fuzzy msgid "The contents of the tooltip for this tray icon" msgstr "የመስኮቱ አርእስት" +#: gtk/gtkstatusicon.c:425 +#, fuzzy +msgid "The title of this tray icon" +msgstr "የመስኮቱ አርእስት" + #: gtk/gtktable.c:129 msgid "Rows" msgstr "ረድፎች" @@ -5766,7 +5894,7 @@ msgid "" "such as PANGO_SCALE_X_LARGE" msgstr "" -#: gtk/gtktexttag.c:360 gtk/gtktextview.c:591 +#: gtk/gtktexttag.c:360 gtk/gtktextview.c:592 msgid "Left, right, or center justification" msgstr "" @@ -5780,7 +5908,7 @@ msgstr "" msgid "Left margin" msgstr "የግራ ህዳግ" -#: gtk/gtktexttag.c:387 gtk/gtktextview.c:600 +#: gtk/gtktexttag.c:387 gtk/gtktextview.c:601 msgid "Width of the left margin in pixels" msgstr "" @@ -5788,15 +5916,15 @@ msgstr "" msgid "Right margin" msgstr "የቀኝ ህዳግ" -#: gtk/gtktexttag.c:397 gtk/gtktextview.c:610 +#: gtk/gtktexttag.c:397 gtk/gtktextview.c:611 msgid "Width of the right margin in pixels" msgstr "" -#: gtk/gtktexttag.c:407 gtk/gtktextview.c:619 +#: gtk/gtktexttag.c:407 gtk/gtktextview.c:620 msgid "Indent" msgstr "አዲስ አንቀጽ" -#: gtk/gtktexttag.c:408 gtk/gtktextview.c:620 +#: gtk/gtktexttag.c:408 gtk/gtktextview.c:621 msgid "Amount to indent the paragraph, in pixels" msgstr "" @@ -5810,7 +5938,7 @@ msgstr "" msgid "Pixels above lines" msgstr "" -#: gtk/gtktexttag.c:429 gtk/gtktextview.c:544 +#: gtk/gtktexttag.c:429 gtk/gtktextview.c:545 msgid "Pixels of blank space above paragraphs" msgstr "" @@ -5818,7 +5946,7 @@ msgstr "" msgid "Pixels below lines" msgstr "" -#: gtk/gtktexttag.c:439 gtk/gtktextview.c:554 +#: gtk/gtktexttag.c:439 gtk/gtktextview.c:555 msgid "Pixels of blank space below paragraphs" msgstr "" @@ -5826,20 +5954,20 @@ msgstr "" msgid "Pixels inside wrap" msgstr "" -#: gtk/gtktexttag.c:449 gtk/gtktextview.c:564 +#: gtk/gtktexttag.c:449 gtk/gtktextview.c:565 msgid "Pixels of blank space between wrapped lines in a paragraph" msgstr "" -#: gtk/gtktexttag.c:476 gtk/gtktextview.c:582 +#: gtk/gtktexttag.c:476 gtk/gtktextview.c:583 msgid "" "Whether to wrap lines never, at word boundaries, or at character boundaries" msgstr "" -#: gtk/gtktexttag.c:485 gtk/gtktextview.c:629 +#: gtk/gtktexttag.c:485 gtk/gtktextview.c:630 msgid "Tabs" msgstr "መክፈቻዎች" -#: gtk/gtktexttag.c:486 gtk/gtktextview.c:630 +#: gtk/gtktexttag.c:486 gtk/gtktextview.c:631 msgid "Custom tabs for this text" msgstr "" @@ -5987,64 +6115,64 @@ msgstr "" msgid "Whether this tag affects the paragraph background color" msgstr "" -#: gtk/gtktextview.c:543 +#: gtk/gtktextview.c:544 msgid "Pixels Above Lines" msgstr "" -#: gtk/gtktextview.c:553 +#: gtk/gtktextview.c:554 msgid "Pixels Below Lines" msgstr "" -#: gtk/gtktextview.c:563 +#: gtk/gtktextview.c:564 msgid "Pixels Inside Wrap" msgstr "" -#: gtk/gtktextview.c:581 +#: gtk/gtktextview.c:582 msgid "Wrap Mode" msgstr "የመሸፈኛ ዘዴ" -#: gtk/gtktextview.c:599 +#: gtk/gtktextview.c:600 msgid "Left Margin" msgstr "የግራ ህዳግ" -#: gtk/gtktextview.c:609 +#: gtk/gtktextview.c:610 msgid "Right Margin" msgstr "የቀኝ ህዳግ" -#: gtk/gtktextview.c:637 +#: gtk/gtktextview.c:638 msgid "Cursor Visible" msgstr "" -#: gtk/gtktextview.c:638 +#: gtk/gtktextview.c:639 msgid "If the insertion cursor is shown" msgstr "" -#: gtk/gtktextview.c:645 +#: gtk/gtktextview.c:646 msgid "Buffer" msgstr "" -#: gtk/gtktextview.c:646 +#: gtk/gtktextview.c:647 msgid "The buffer which is displayed" msgstr "" -#: gtk/gtktextview.c:654 +#: gtk/gtktextview.c:655 msgid "Whether entered text overwrites existing contents" msgstr "" -#: gtk/gtktextview.c:661 +#: gtk/gtktextview.c:662 msgid "Accepts tab" msgstr "" -#: gtk/gtktextview.c:662 +#: gtk/gtktextview.c:663 msgid "Whether Tab will result in a tab character being entered" msgstr "" -#: gtk/gtktextview.c:691 +#: gtk/gtktextview.c:692 #, fuzzy msgid "Error underline color" msgstr "የፊት ለፊቱ ቀለም" -#: gtk/gtktextview.c:692 +#: gtk/gtktextview.c:693 msgid "Color with which to draw error-indication underlines" msgstr "" @@ -6229,345 +6357,354 @@ msgstr "ክፍተት" msgid "Spacing in pixels between the icon and label" msgstr "" -#: gtk/gtktoolitem.c:191 +#: gtk/gtktoolitem.c:207 msgid "" "Whether the toolbar item is considered important. When TRUE, toolbar buttons " "show text in GTK_TOOLBAR_BOTH_HORIZ mode" msgstr "" -#: gtk/gtktreemodelsort.c:274 +#: gtk/gtktreemodelsort.c:278 msgid "TreeModelSort Model" msgstr "" -#: gtk/gtktreemodelsort.c:275 +#: gtk/gtktreemodelsort.c:279 msgid "The model for the TreeModelSort to sort" msgstr "" -#: gtk/gtktreeview.c:570 +#: gtk/gtktreeview.c:561 msgid "TreeView Model" msgstr "" -#: gtk/gtktreeview.c:571 +#: gtk/gtktreeview.c:562 msgid "The model for the tree view" msgstr "" -#: gtk/gtktreeview.c:579 +#: gtk/gtktreeview.c:570 msgid "Horizontal Adjustment for the widget" msgstr "" -#: gtk/gtktreeview.c:587 +#: gtk/gtktreeview.c:578 msgid "Vertical Adjustment for the widget" msgstr "" -#: gtk/gtktreeview.c:594 +#: gtk/gtktreeview.c:585 #, fuzzy msgid "Headers Visible" msgstr "የሚታይ" -#: gtk/gtktreeview.c:595 +#: gtk/gtktreeview.c:586 msgid "Show the column header buttons" msgstr "" -#: gtk/gtktreeview.c:602 +#: gtk/gtktreeview.c:593 msgid "Headers Clickable" msgstr "" -#: gtk/gtktreeview.c:603 +#: gtk/gtktreeview.c:594 msgid "Column headers respond to click events" msgstr "" -#: gtk/gtktreeview.c:610 +#: gtk/gtktreeview.c:601 msgid "Expander Column" msgstr "" -#: gtk/gtktreeview.c:611 +#: gtk/gtktreeview.c:602 msgid "Set the column for the expander column" msgstr "" -#: gtk/gtktreeview.c:626 +#: gtk/gtktreeview.c:617 msgid "Rules Hint" msgstr "" -#: gtk/gtktreeview.c:627 +#: gtk/gtktreeview.c:618 msgid "Set a hint to the theme engine to draw rows in alternating colors" msgstr "" -#: gtk/gtktreeview.c:634 +#: gtk/gtktreeview.c:625 msgid "Enable Search" msgstr "" -#: gtk/gtktreeview.c:635 +#: gtk/gtktreeview.c:626 msgid "View allows user to search through columns interactively" msgstr "" -#: gtk/gtktreeview.c:642 +#: gtk/gtktreeview.c:633 msgid "Search Column" msgstr "" -#: gtk/gtktreeview.c:643 +#: gtk/gtktreeview.c:634 msgid "Model column to search through during interactive search" msgstr "" -#: gtk/gtktreeview.c:663 +#: gtk/gtktreeview.c:654 msgid "Fixed Height Mode" msgstr "" -#: gtk/gtktreeview.c:664 +#: gtk/gtktreeview.c:655 msgid "Speeds up GtkTreeView by assuming that all rows have the same height" msgstr "" -#: gtk/gtktreeview.c:684 +#: gtk/gtktreeview.c:675 msgid "Hover Selection" msgstr "" -#: gtk/gtktreeview.c:685 +#: gtk/gtktreeview.c:676 msgid "Whether the selection should follow the pointer" msgstr "" -#: gtk/gtktreeview.c:704 +#: gtk/gtktreeview.c:695 msgid "Hover Expand" msgstr "" -#: gtk/gtktreeview.c:705 +#: gtk/gtktreeview.c:696 msgid "" "Whether rows should be expanded/collapsed when the pointer moves over them" msgstr "" -#: gtk/gtktreeview.c:719 +#: gtk/gtktreeview.c:710 #, fuzzy msgid "Show Expanders" msgstr "ማስረጊያዎች አሳይ" -#: gtk/gtktreeview.c:720 +#: gtk/gtktreeview.c:711 msgid "View has expanders" msgstr "" -#: gtk/gtktreeview.c:734 +#: gtk/gtktreeview.c:725 msgid "Level Indentation" msgstr "" -#: gtk/gtktreeview.c:735 +#: gtk/gtktreeview.c:726 msgid "Extra indentation for each level" msgstr "" -#: gtk/gtktreeview.c:744 +#: gtk/gtktreeview.c:735 msgid "Rubber Banding" msgstr "" -#: gtk/gtktreeview.c:745 +#: gtk/gtktreeview.c:736 msgid "" "Whether to enable selection of multiple items by dragging the mouse pointer" msgstr "" -#: gtk/gtktreeview.c:752 +#: gtk/gtktreeview.c:743 msgid "Enable Grid Lines" msgstr "" -#: gtk/gtktreeview.c:753 +#: gtk/gtktreeview.c:744 msgid "Whether grid lines should be drawn in the tree view" msgstr "" -#: gtk/gtktreeview.c:761 +#: gtk/gtktreeview.c:752 msgid "Enable Tree Lines" msgstr "" -#: gtk/gtktreeview.c:762 +#: gtk/gtktreeview.c:753 msgid "Whether tree lines should be drawn in the tree view" msgstr "" -#: gtk/gtktreeview.c:770 +#: gtk/gtktreeview.c:761 msgid "The column in the model containing the tooltip texts for the rows" msgstr "" -#: gtk/gtktreeview.c:792 +#: gtk/gtktreeview.c:783 msgid "Vertical Separator Width" msgstr "" -#: gtk/gtktreeview.c:793 +#: gtk/gtktreeview.c:784 msgid "Vertical space between cells. Must be an even number" msgstr "" -#: gtk/gtktreeview.c:801 +#: gtk/gtktreeview.c:792 msgid "Horizontal Separator Width" msgstr "" -#: gtk/gtktreeview.c:802 +#: gtk/gtktreeview.c:793 msgid "Horizontal space between cells. Must be an even number" msgstr "" -#: gtk/gtktreeview.c:810 +#: gtk/gtktreeview.c:801 msgid "Allow Rules" msgstr "" -#: gtk/gtktreeview.c:811 +#: gtk/gtktreeview.c:802 msgid "Allow drawing of alternating color rows" msgstr "" -#: gtk/gtktreeview.c:817 +#: gtk/gtktreeview.c:808 msgid "Indent Expanders" msgstr "" -#: gtk/gtktreeview.c:818 +#: gtk/gtktreeview.c:809 msgid "Make the expanders indented" msgstr "" -#: gtk/gtktreeview.c:824 +#: gtk/gtktreeview.c:815 msgid "Even Row Color" msgstr "" -#: gtk/gtktreeview.c:825 +#: gtk/gtktreeview.c:816 msgid "Color to use for even rows" msgstr "" -#: gtk/gtktreeview.c:831 +#: gtk/gtktreeview.c:822 msgid "Odd Row Color" msgstr "" -#: gtk/gtktreeview.c:832 +#: gtk/gtktreeview.c:823 msgid "Color to use for odd rows" msgstr "" -#: gtk/gtktreeview.c:838 +#: gtk/gtktreeview.c:829 msgid "Row Ending details" msgstr "" -#: gtk/gtktreeview.c:839 +#: gtk/gtktreeview.c:830 msgid "Enable extended row background theming" msgstr "" -#: gtk/gtktreeview.c:845 +#: gtk/gtktreeview.c:836 msgid "Grid line width" msgstr "" -#: gtk/gtktreeview.c:846 +#: gtk/gtktreeview.c:837 msgid "Width, in pixels, of the tree view grid lines" msgstr "" -#: gtk/gtktreeview.c:852 +#: gtk/gtktreeview.c:843 #, fuzzy msgid "Tree line width" msgstr "የጽሑፉ ቅድመ ዕይታ" -#: gtk/gtktreeview.c:853 +#: gtk/gtktreeview.c:844 msgid "Width, in pixels, of the tree view lines" msgstr "" -#: gtk/gtktreeview.c:859 +#: gtk/gtktreeview.c:850 msgid "Grid line pattern" msgstr "" -#: gtk/gtktreeview.c:860 +#: gtk/gtktreeview.c:851 msgid "Dash pattern used to draw the tree view grid lines" msgstr "" -#: gtk/gtktreeview.c:866 +#: gtk/gtktreeview.c:857 msgid "Tree line pattern" msgstr "" -#: gtk/gtktreeview.c:867 +#: gtk/gtktreeview.c:858 msgid "Dash pattern used to draw the tree view lines" msgstr "" -#: gtk/gtktreeviewcolumn.c:192 +#: gtk/gtktreeviewcolumn.c:193 msgid "Whether to display the column" msgstr "" -#: gtk/gtktreeviewcolumn.c:199 gtk/gtkwindow.c:537 +#: gtk/gtktreeviewcolumn.c:200 gtk/gtkwindow.c:537 msgid "Resizable" msgstr "" -#: gtk/gtktreeviewcolumn.c:200 +#: gtk/gtktreeviewcolumn.c:201 msgid "Column is user-resizable" msgstr "" -#: gtk/gtktreeviewcolumn.c:208 +#: gtk/gtktreeviewcolumn.c:209 msgid "Current width of the column" msgstr "" -#: gtk/gtktreeviewcolumn.c:217 +#: gtk/gtktreeviewcolumn.c:218 msgid "Space which is inserted between cells" msgstr "" -#: gtk/gtktreeviewcolumn.c:225 +#: gtk/gtktreeviewcolumn.c:226 msgid "Sizing" msgstr "" -#: gtk/gtktreeviewcolumn.c:226 +#: gtk/gtktreeviewcolumn.c:227 msgid "Resize mode of the column" msgstr "" -#: gtk/gtktreeviewcolumn.c:234 +#: gtk/gtktreeviewcolumn.c:235 msgid "Fixed Width" msgstr "" -#: gtk/gtktreeviewcolumn.c:235 +#: gtk/gtktreeviewcolumn.c:236 msgid "Current fixed width of the column" msgstr "" -#: gtk/gtktreeviewcolumn.c:244 +#: gtk/gtktreeviewcolumn.c:245 msgid "Minimum Width" msgstr "" -#: gtk/gtktreeviewcolumn.c:245 +#: gtk/gtktreeviewcolumn.c:246 msgid "Minimum allowed width of the column" msgstr "" -#: gtk/gtktreeviewcolumn.c:254 +#: gtk/gtktreeviewcolumn.c:255 msgid "Maximum Width" msgstr "" -#: gtk/gtktreeviewcolumn.c:255 +#: gtk/gtktreeviewcolumn.c:256 msgid "Maximum allowed width of the column" msgstr "" -#: gtk/gtktreeviewcolumn.c:265 +#: gtk/gtktreeviewcolumn.c:266 msgid "Title to appear in column header" msgstr "" -#: gtk/gtktreeviewcolumn.c:273 +#: gtk/gtktreeviewcolumn.c:274 msgid "Column gets share of extra width allocated to the widget" msgstr "" -#: gtk/gtktreeviewcolumn.c:280 +#: gtk/gtktreeviewcolumn.c:281 msgid "Clickable" msgstr "" -#: gtk/gtktreeviewcolumn.c:281 +#: gtk/gtktreeviewcolumn.c:282 msgid "Whether the header can be clicked" msgstr "" -#: gtk/gtktreeviewcolumn.c:289 +#: gtk/gtktreeviewcolumn.c:290 msgid "Widget" msgstr "" -#: gtk/gtktreeviewcolumn.c:290 +#: gtk/gtktreeviewcolumn.c:291 msgid "Widget to put in column header button instead of column title" msgstr "" -#: gtk/gtktreeviewcolumn.c:298 +#: gtk/gtktreeviewcolumn.c:299 msgid "X Alignment of the column header text or widget" msgstr "" -#: gtk/gtktreeviewcolumn.c:308 +#: gtk/gtktreeviewcolumn.c:309 msgid "Whether the column can be reordered around the headers" msgstr "" -#: gtk/gtktreeviewcolumn.c:315 +#: gtk/gtktreeviewcolumn.c:316 msgid "Sort indicator" msgstr "" -#: gtk/gtktreeviewcolumn.c:316 +#: gtk/gtktreeviewcolumn.c:317 msgid "Whether to show a sort indicator" msgstr "" -#: gtk/gtktreeviewcolumn.c:323 +#: gtk/gtktreeviewcolumn.c:324 msgid "Sort order" msgstr "ቅደም ተከተል" -#: gtk/gtktreeviewcolumn.c:324 +#: gtk/gtktreeviewcolumn.c:325 msgid "Sort direction the sort indicator should indicate" msgstr "" +#: gtk/gtktreeviewcolumn.c:341 +#, fuzzy +msgid "Sort column ID" +msgstr "ዐምዶች" + +#: gtk/gtktreeviewcolumn.c:342 +msgid "Logical sort column ID this column sorts on when selected for sorting" +msgstr "" + #: gtk/gtkuimanager.c:223 msgid "Whether tearoff menu items should be added to menus" msgstr "" @@ -6596,290 +6733,298 @@ msgstr "" msgid "Determines how the shadowed box around the viewport is drawn" msgstr "" -#: gtk/gtkwidget.c:483 +#: gtk/gtkwidget.c:485 msgid "Widget name" msgstr "" -#: gtk/gtkwidget.c:484 +#: gtk/gtkwidget.c:486 msgid "The name of the widget" msgstr "" -#: gtk/gtkwidget.c:490 +#: gtk/gtkwidget.c:492 msgid "Parent widget" msgstr "" -#: gtk/gtkwidget.c:491 +#: gtk/gtkwidget.c:493 msgid "The parent widget of this widget. Must be a Container widget" msgstr "" -#: gtk/gtkwidget.c:498 +#: gtk/gtkwidget.c:500 msgid "Width request" msgstr "" -#: gtk/gtkwidget.c:499 +#: gtk/gtkwidget.c:501 msgid "" "Override for width request of the widget, or -1 if natural request should be " "used" msgstr "" -#: gtk/gtkwidget.c:507 +#: gtk/gtkwidget.c:509 msgid "Height request" msgstr "" -#: gtk/gtkwidget.c:508 +#: gtk/gtkwidget.c:510 msgid "" "Override for height request of the widget, or -1 if natural request should " "be used" msgstr "" -#: gtk/gtkwidget.c:517 +#: gtk/gtkwidget.c:519 msgid "Whether the widget is visible" msgstr "" -#: gtk/gtkwidget.c:524 +#: gtk/gtkwidget.c:526 msgid "Whether the widget responds to input" msgstr "" -#: gtk/gtkwidget.c:530 +#: gtk/gtkwidget.c:532 msgid "Application paintable" msgstr "" -#: gtk/gtkwidget.c:531 +#: gtk/gtkwidget.c:533 msgid "Whether the application will paint directly on the widget" msgstr "" -#: gtk/gtkwidget.c:537 +#: gtk/gtkwidget.c:539 msgid "Can focus" msgstr "" -#: gtk/gtkwidget.c:538 +#: gtk/gtkwidget.c:540 msgid "Whether the widget can accept the input focus" msgstr "" -#: gtk/gtkwidget.c:544 +#: gtk/gtkwidget.c:546 msgid "Has focus" msgstr "" -#: gtk/gtkwidget.c:545 +#: gtk/gtkwidget.c:547 msgid "Whether the widget has the input focus" msgstr "" -#: gtk/gtkwidget.c:551 +#: gtk/gtkwidget.c:553 msgid "Is focus" msgstr "" -#: gtk/gtkwidget.c:552 +#: gtk/gtkwidget.c:554 msgid "Whether the widget is the focus widget within the toplevel" msgstr "" -#: gtk/gtkwidget.c:558 +#: gtk/gtkwidget.c:560 msgid "Can default" msgstr "" -#: gtk/gtkwidget.c:559 +#: gtk/gtkwidget.c:561 msgid "Whether the widget can be the default widget" msgstr "" -#: gtk/gtkwidget.c:565 +#: gtk/gtkwidget.c:567 msgid "Has default" msgstr "" -#: gtk/gtkwidget.c:566 +#: gtk/gtkwidget.c:568 msgid "Whether the widget is the default widget" msgstr "" -#: gtk/gtkwidget.c:572 +#: gtk/gtkwidget.c:574 msgid "Receives default" msgstr "" -#: gtk/gtkwidget.c:573 +#: gtk/gtkwidget.c:575 msgid "If TRUE, the widget will receive the default action when it is focused" msgstr "" -#: gtk/gtkwidget.c:579 +#: gtk/gtkwidget.c:581 msgid "Composite child" msgstr "" -#: gtk/gtkwidget.c:580 +#: gtk/gtkwidget.c:582 msgid "Whether the widget is part of a composite widget" msgstr "" -#: gtk/gtkwidget.c:586 +#: gtk/gtkwidget.c:588 msgid "Style" msgstr "ዘይቤ" -#: gtk/gtkwidget.c:587 +#: gtk/gtkwidget.c:589 msgid "" "The style of the widget, which contains information about how it will look " "(colors etc)" msgstr "" -#: gtk/gtkwidget.c:593 +#: gtk/gtkwidget.c:595 msgid "Events" msgstr "" -#: gtk/gtkwidget.c:594 +#: gtk/gtkwidget.c:596 msgid "The event mask that decides what kind of GdkEvents this widget gets" msgstr "" -#: gtk/gtkwidget.c:601 +#: gtk/gtkwidget.c:603 msgid "Extension events" msgstr "" -#: gtk/gtkwidget.c:602 +#: gtk/gtkwidget.c:604 msgid "The mask that decides what kind of extension events this widget gets" msgstr "" -#: gtk/gtkwidget.c:609 +#: gtk/gtkwidget.c:611 msgid "No show all" msgstr "" -#: gtk/gtkwidget.c:610 +#: gtk/gtkwidget.c:612 msgid "Whether gtk_widget_show_all() should not affect this widget" msgstr "" -#: gtk/gtkwidget.c:633 +#: gtk/gtkwidget.c:635 msgid "Whether this widget has a tooltip" msgstr "" -#: gtk/gtkwidget.c:689 +#: gtk/gtkwidget.c:691 #, fuzzy msgid "Window" msgstr "የመስኮት ዓይነት" -#: gtk/gtkwidget.c:690 +#: gtk/gtkwidget.c:692 msgid "The widget's window if it is realized" msgstr "" -#: gtk/gtkwidget.c:2212 +#: gtk/gtkwidget.c:706 +msgid "Double Buffered" +msgstr "" + +#: gtk/gtkwidget.c:707 +msgid "Whether or not the widget is double buffered" +msgstr "" + +#: gtk/gtkwidget.c:2229 msgid "Interior Focus" msgstr "" -#: gtk/gtkwidget.c:2213 +#: gtk/gtkwidget.c:2230 msgid "Whether to draw the focus indicator inside widgets" msgstr "" -#: gtk/gtkwidget.c:2219 +#: gtk/gtkwidget.c:2236 msgid "Focus linewidth" msgstr "" -#: gtk/gtkwidget.c:2220 +#: gtk/gtkwidget.c:2237 msgid "Width, in pixels, of the focus indicator line" msgstr "" -#: gtk/gtkwidget.c:2226 +#: gtk/gtkwidget.c:2243 msgid "Focus line dash pattern" msgstr "" -#: gtk/gtkwidget.c:2227 +#: gtk/gtkwidget.c:2244 msgid "Dash pattern used to draw the focus indicator" msgstr "" -#: gtk/gtkwidget.c:2232 +#: gtk/gtkwidget.c:2249 msgid "Focus padding" msgstr "" -#: gtk/gtkwidget.c:2233 +#: gtk/gtkwidget.c:2250 msgid "Width, in pixels, between focus indicator and the widget 'box'" msgstr "" -#: gtk/gtkwidget.c:2238 +#: gtk/gtkwidget.c:2255 msgid "Cursor color" msgstr "የጠቋሚው ቀለም" -#: gtk/gtkwidget.c:2239 +#: gtk/gtkwidget.c:2256 msgid "Color with which to draw insertion cursor" msgstr "" -#: gtk/gtkwidget.c:2244 +#: gtk/gtkwidget.c:2261 msgid "Secondary cursor color" msgstr "" -#: gtk/gtkwidget.c:2245 +#: gtk/gtkwidget.c:2262 msgid "" "Color with which to draw the secondary insertion cursor when editing mixed " "right-to-left and left-to-right text" msgstr "" -#: gtk/gtkwidget.c:2250 +#: gtk/gtkwidget.c:2267 msgid "Cursor line aspect ratio" msgstr "" -#: gtk/gtkwidget.c:2251 +#: gtk/gtkwidget.c:2268 msgid "Aspect ratio with which to draw insertion cursor" msgstr "" -#: gtk/gtkwidget.c:2265 +#: gtk/gtkwidget.c:2282 #, fuzzy msgid "Draw Border" msgstr "ቅደም ተከተል" -#: gtk/gtkwidget.c:2266 +#: gtk/gtkwidget.c:2283 msgid "Size of areas outside the widget's allocation to draw" msgstr "" -#: gtk/gtkwidget.c:2279 +#: gtk/gtkwidget.c:2296 #, fuzzy msgid "Unvisited Link Color" msgstr "የአሁኑን ቀለም" -#: gtk/gtkwidget.c:2280 +#: gtk/gtkwidget.c:2297 #, fuzzy msgid "Color of unvisited links" msgstr "የመስኮቱ አርእስት" -#: gtk/gtkwidget.c:2293 +#: gtk/gtkwidget.c:2310 #, fuzzy msgid "Visited Link Color" msgstr "የአሁኑን ቀለም" -#: gtk/gtkwidget.c:2294 +#: gtk/gtkwidget.c:2311 #, fuzzy msgid "Color of visited links" msgstr "የመስኮቱ አርእስት" -#: gtk/gtkwidget.c:2308 +#: gtk/gtkwidget.c:2325 msgid "Wide Separators" msgstr "" -#: gtk/gtkwidget.c:2309 +#: gtk/gtkwidget.c:2326 msgid "" "Whether separators have configurable width and should be drawn using a box " "instead of a line" msgstr "" -#: gtk/gtkwidget.c:2323 +#: gtk/gtkwidget.c:2340 #, fuzzy msgid "Separator Width" msgstr "የነበረው ስፋት" -#: gtk/gtkwidget.c:2324 +#: gtk/gtkwidget.c:2341 msgid "The width of separators if wide-separators is TRUE" msgstr "" -#: gtk/gtkwidget.c:2338 +#: gtk/gtkwidget.c:2355 #, fuzzy msgid "Separator Height" msgstr "የነበረው እርዝማኔ" -#: gtk/gtkwidget.c:2339 +#: gtk/gtkwidget.c:2356 msgid "The height of separators if \"wide-separators\" is TRUE" msgstr "" -#: gtk/gtkwidget.c:2353 +#: gtk/gtkwidget.c:2370 #, fuzzy msgid "Horizontal Scroll Arrow Length" msgstr "የአግድም ኩልኩል" -#: gtk/gtkwidget.c:2354 +#: gtk/gtkwidget.c:2371 msgid "The length of horizontal scroll arrows" msgstr "" -#: gtk/gtkwidget.c:2368 +#: gtk/gtkwidget.c:2385 msgid "Vertical Scroll Arrow Length" msgstr "" -#: gtk/gtkwidget.c:2369 +#: gtk/gtkwidget.c:2386 msgid "The length of vertical scroll arrows" msgstr "" diff --git a/po-properties/ang.po b/po-properties/ang.po index e941081c56..a323d9b9b7 100644 --- a/po-properties/ang.po +++ b/po-properties/ang.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: gtk+-properties OE\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-06-15 20:53-0400\n" +"POT-Creation-Date: 2009-09-30 17:31-0400\n" "PO-Revision-Date: 2004-08-26 16:32-0600\n" "Last-Translator: James Johnson \n" "Language-Team: Old English \n" @@ -15,6 +15,14 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +#: gdk-pixbuf/gdk-pixbuf-simple-anim.c:165 +msgid "Loop" +msgstr "" + +#: gdk-pixbuf/gdk-pixbuf-simple-anim.c:166 +msgid "Whether the animation should loop when it reaches the end" +msgstr "" + #: gdk-pixbuf/gdk-pixbuf.c:89 msgid "Number of Channels" msgstr "Gerím channela" @@ -47,7 +55,7 @@ msgstr "" msgid "The number of bits per sample" msgstr "" -#: gdk-pixbuf/gdk-pixbuf.c:132 gtk/gtklayout.c:632 gtk/gtktreeviewcolumn.c:207 +#: gdk-pixbuf/gdk-pixbuf.c:132 gtk/gtklayout.c:632 gtk/gtktreeviewcolumn.c:208 msgid "Width" msgstr "Wídu" @@ -88,12 +96,12 @@ msgstr "" msgid "The default display for GDK" msgstr "" -#: gdk/gdkpango.c:537 gtk/gtkinvisible.c:86 gtk/gtkmountoperation.c:155 -#: gtk/gtkstatusicon.c:277 gtk/gtkwindow.c:614 +#: gdk/gdkpango.c:538 gtk/gtkinvisible.c:86 gtk/gtkmountoperation.c:176 +#: gtk/gtkstatusicon.c:280 gtk/gtkwindow.c:614 msgid "Screen" msgstr "" -#: gdk/gdkpango.c:538 +#: gdk/gdkpango.c:539 msgid "the GdkScreen for the renderer" msgstr "" @@ -113,6 +121,10 @@ msgstr "" msgid "The resolution for fonts on the screen" msgstr "" +#: gdk/gdkwindow.c:472 gdk/gdkwindow.c:473 +msgid "Cursor" +msgstr "" + #: gtk/gtkaboutdialog.c:239 msgid "Program name" msgstr "" @@ -250,7 +262,7 @@ msgid "A unique name for the action." msgstr "" #: gtk/gtkaction.c:198 gtk/gtkbutton.c:219 gtk/gtkexpander.c:195 -#: gtk/gtkframe.c:105 gtk/gtklabel.c:495 gtk/gtkmenuitem.c:300 +#: gtk/gtkframe.c:105 gtk/gtklabel.c:496 gtk/gtkmenuitem.c:305 #: gtk/gtktoolbutton.c:202 msgid "Label" msgstr "" @@ -283,32 +295,32 @@ msgstr "" msgid "The stock icon displayed in widgets representing this action." msgstr "" -#: gtk/gtkaction.c:261 gtk/gtkstatusicon.c:250 +#: gtk/gtkaction.c:261 gtk/gtkstatusicon.c:253 #, fuzzy msgid "GIcon" msgstr "Segn" #: gtk/gtkaction.c:262 gtk/gtkcellrendererpixbuf.c:206 gtk/gtkimage.c:248 -#: gtk/gtkstatusicon.c:251 +#: gtk/gtkstatusicon.c:254 msgid "The GIcon being displayed" msgstr "" #: gtk/gtkaction.c:282 gtk/gtkcellrendererpixbuf.c:171 gtk/gtkimage.c:230 -#: gtk/gtkprinter.c:172 gtk/gtkstatusicon.c:234 gtk/gtkwindow.c:606 +#: gtk/gtkprinter.c:172 gtk/gtkstatusicon.c:237 gtk/gtkwindow.c:606 #, fuzzy msgid "Icon Name" msgstr "Nama" #: gtk/gtkaction.c:283 gtk/gtkcellrendererpixbuf.c:172 gtk/gtkimage.c:231 -#: gtk/gtkstatusicon.c:235 +#: gtk/gtkstatusicon.c:238 msgid "The name of the icon from the icon theme" msgstr "" -#: gtk/gtkaction.c:290 gtk/gtktoolitem.c:176 +#: gtk/gtkaction.c:290 gtk/gtktoolitem.c:192 msgid "Visible when horizontal" msgstr "" -#: gtk/gtkaction.c:291 gtk/gtktoolitem.c:177 +#: gtk/gtkaction.c:291 gtk/gtktoolitem.c:193 msgid "" "Whether the toolbar item is visible when the toolbar is in a horizontal " "orientation." @@ -324,17 +336,17 @@ msgid "" "overflow menu." msgstr "" -#: gtk/gtkaction.c:314 gtk/gtktoolitem.c:183 +#: gtk/gtkaction.c:314 gtk/gtktoolitem.c:199 msgid "Visible when vertical" msgstr "" -#: gtk/gtkaction.c:315 gtk/gtktoolitem.c:184 +#: gtk/gtkaction.c:315 gtk/gtktoolitem.c:200 msgid "" "Whether the toolbar item is visible when the toolbar is in a vertical " "orientation." msgstr "" -#: gtk/gtkaction.c:322 gtk/gtktoolitem.c:190 +#: gtk/gtkaction.c:322 gtk/gtktoolitem.c:206 msgid "Is important" msgstr "" @@ -353,7 +365,7 @@ msgid "When TRUE, empty menu proxies for this action are hidden." msgstr "" #: gtk/gtkaction.c:338 gtk/gtkactiongroup.c:177 gtk/gtkcellrenderer.c:193 -#: gtk/gtkwidget.c:523 +#: gtk/gtkwidget.c:525 msgid "Sensitive" msgstr "" @@ -361,8 +373,8 @@ msgstr "" msgid "Whether the action is enabled." msgstr "" -#: gtk/gtkaction.c:345 gtk/gtkactiongroup.c:184 gtk/gtkstatusicon.c:293 -#: gtk/gtktreeviewcolumn.c:191 gtk/gtkwidget.c:516 +#: gtk/gtkaction.c:345 gtk/gtkactiongroup.c:184 gtk/gtkstatusicon.c:296 +#: gtk/gtktreeviewcolumn.c:192 gtk/gtkwidget.c:518 msgid "Visible" msgstr "" @@ -392,6 +404,22 @@ msgstr "" msgid "Whether the action group is visible." msgstr "" +#: gtk/gtkactivatable.c:304 +msgid "Related Action" +msgstr "" + +#: gtk/gtkactivatable.c:305 +msgid "The action this activatable will activate and receive updates from" +msgstr "" + +#: gtk/gtkactivatable.c:327 +msgid "Use Action Appearance" +msgstr "" + +#: gtk/gtkactivatable.c:328 +msgid "Whether to use the related actions appearance properties" +msgstr "" + #: gtk/gtkadjustment.c:93 gtk/gtkcellrendererprogress.c:128 #: gtk/gtkscalebutton.c:206 gtk/gtkspinbutton.c:269 msgid "Value" @@ -529,7 +557,7 @@ msgstr "" msgid "Appearance of the shadow surrounding the arrow" msgstr "" -#: gtk/gtkarrow.c:92 gtk/gtkmenu.c:689 gtk/gtkmenuitem.c:363 +#: gtk/gtkarrow.c:92 gtk/gtkmenu.c:711 gtk/gtkmenuitem.c:368 msgid "Arrow Scaling" msgstr "" @@ -627,60 +655,60 @@ msgstr "" msgid "Whether all required fields on the page have been filled out" msgstr "" -#: gtk/gtkbbox.c:99 +#: gtk/gtkbbox.c:101 msgid "Minimum child width" msgstr "" -#: gtk/gtkbbox.c:100 +#: gtk/gtkbbox.c:102 msgid "Minimum width of buttons inside the box" msgstr "" -#: gtk/gtkbbox.c:108 +#: gtk/gtkbbox.c:110 msgid "Minimum child height" msgstr "" -#: gtk/gtkbbox.c:109 +#: gtk/gtkbbox.c:111 msgid "Minimum height of buttons inside the box" msgstr "" -#: gtk/gtkbbox.c:117 +#: gtk/gtkbbox.c:119 msgid "Child internal width padding" msgstr "" -#: gtk/gtkbbox.c:118 +#: gtk/gtkbbox.c:120 msgid "Amount to increase child's size on either side" msgstr "" -#: gtk/gtkbbox.c:126 +#: gtk/gtkbbox.c:128 msgid "Child internal height padding" msgstr "" -#: gtk/gtkbbox.c:127 +#: gtk/gtkbbox.c:129 msgid "Amount to increase child's size on the top and bottom" msgstr "" -#: gtk/gtkbbox.c:135 +#: gtk/gtkbbox.c:137 msgid "Layout style" msgstr "" -#: gtk/gtkbbox.c:136 +#: gtk/gtkbbox.c:138 msgid "" "How to layout the buttons in the box. Possible values are default, spread, " "edge, start and end" msgstr "" -#: gtk/gtkbbox.c:144 +#: gtk/gtkbbox.c:146 msgid "Secondary" msgstr "" -#: gtk/gtkbbox.c:145 +#: gtk/gtkbbox.c:147 msgid "" "If TRUE, the child appears in a secondary group of children, suitable for, e." "g., help buttons" msgstr "" -#: gtk/gtkbox.c:130 gtk/gtkexpander.c:219 gtk/gtkiconview.c:664 -#: gtk/gtktreeviewcolumn.c:216 +#: gtk/gtkbox.c:130 gtk/gtkexpander.c:219 gtk/gtkiconview.c:665 +#: gtk/gtktreeviewcolumn.c:217 msgid "Spacing" msgstr "" @@ -698,7 +726,7 @@ msgid "Whether the children should all be the same size" msgstr "" #: gtk/gtkbox.c:148 gtk/gtkpreview.c:101 gtk/gtktoolbar.c:565 -#: gtk/gtktreeviewcolumn.c:272 +#: gtk/gtktreeviewcolumn.c:273 msgid "Expand" msgstr "" @@ -757,13 +785,13 @@ msgid "" "widget" msgstr "" -#: gtk/gtkbutton.c:227 gtk/gtkexpander.c:203 gtk/gtklabel.c:516 -#: gtk/gtkmenuitem.c:315 gtk/gtktoolbutton.c:209 +#: gtk/gtkbutton.c:227 gtk/gtkexpander.c:203 gtk/gtklabel.c:517 +#: gtk/gtkmenuitem.c:320 gtk/gtktoolbutton.c:209 msgid "Use underline" msgstr "" -#: gtk/gtkbutton.c:228 gtk/gtkexpander.c:204 gtk/gtklabel.c:517 -#: gtk/gtkmenuitem.c:316 +#: gtk/gtkbutton.c:228 gtk/gtkexpander.c:204 gtk/gtklabel.c:518 +#: gtk/gtkmenuitem.c:321 msgid "" "If set, an underline in the text indicates the next character should be used " "for the mnemonic accelerator key" @@ -778,7 +806,7 @@ msgid "" "If set, the label is used to pick a stock item instead of being displayed" msgstr "" -#: gtk/gtkbutton.c:243 gtk/gtkcombobox.c:789 gtk/gtkfilechooserbutton.c:393 +#: gtk/gtkbutton.c:243 gtk/gtkcombobox.c:791 gtk/gtkfilechooserbutton.c:393 msgid "Focus on click" msgstr "" @@ -864,7 +892,7 @@ msgid "" "rectangle" msgstr "" -#: gtk/gtkbutton.c:485 gtk/gtkentry.c:658 gtk/gtkentry.c:1682 +#: gtk/gtkbutton.c:485 gtk/gtkentry.c:689 gtk/gtkentry.c:1713 msgid "Inner Border" msgstr "" @@ -1089,35 +1117,35 @@ msgstr "" msgid "Whether this tag affects the cell background color" msgstr "" -#: gtk/gtkcellrendereraccel.c:113 +#: gtk/gtkcellrendereraccel.c:114 msgid "Accelerator key" msgstr "" -#: gtk/gtkcellrendereraccel.c:114 +#: gtk/gtkcellrendereraccel.c:115 msgid "The keyval of the accelerator" msgstr "" -#: gtk/gtkcellrendereraccel.c:130 +#: gtk/gtkcellrendereraccel.c:131 msgid "Accelerator modifiers" msgstr "" -#: gtk/gtkcellrendereraccel.c:131 +#: gtk/gtkcellrendereraccel.c:132 msgid "The modifier mask of the accelerator" msgstr "" -#: gtk/gtkcellrendereraccel.c:148 +#: gtk/gtkcellrendereraccel.c:149 msgid "Accelerator keycode" msgstr "" -#: gtk/gtkcellrendereraccel.c:149 +#: gtk/gtkcellrendereraccel.c:150 msgid "The hardware keycode of the accelerator" msgstr "" -#: gtk/gtkcellrendereraccel.c:168 +#: gtk/gtkcellrendereraccel.c:169 msgid "Accelerator Mode" msgstr "" -#: gtk/gtkcellrendereraccel.c:169 +#: gtk/gtkcellrendereraccel.c:170 #, fuzzy msgid "The type of accelerators" msgstr "Þæt cynn þæs éagþyrles" @@ -1170,7 +1198,7 @@ msgstr "" msgid "Pixbuf for closed expander" msgstr "" -#: gtk/gtkcellrendererpixbuf.c:135 gtk/gtkimage.c:172 gtk/gtkstatusicon.c:226 +#: gtk/gtkcellrendererpixbuf.c:135 gtk/gtkimage.c:172 gtk/gtkstatusicon.c:229 msgid "Stock ID" msgstr "" @@ -1179,7 +1207,7 @@ msgid "The stock ID of the stock icon to render" msgstr "" #: gtk/gtkcellrendererpixbuf.c:143 gtk/gtkrecentmanager.c:245 -#: gtk/gtkstatusicon.c:267 +#: gtk/gtkstatusicon.c:270 msgid "Size" msgstr "" @@ -1212,8 +1240,8 @@ msgid "Value of the progress bar" msgstr "" #: gtk/gtkcellrendererprogress.c:146 gtk/gtkcellrenderertext.c:195 -#: gtk/gtkentry.c:701 gtk/gtkmessagedialog.c:153 gtk/gtkprogressbar.c:184 -#: gtk/gtktextbuffer.c:198 +#: gtk/gtkentry.c:732 gtk/gtkentrybuffer.c:353 gtk/gtkmessagedialog.c:153 +#: gtk/gtkprogressbar.c:184 gtk/gtktextbuffer.c:198 msgid "Text" msgstr "" @@ -1250,7 +1278,7 @@ msgid "The vertical text alignment, from 0 (top) to 1 (bottom)." msgstr "" #: gtk/gtkcellrendererprogress.c:221 gtk/gtkiconview.c:729 -#: gtk/gtkorientable.c:74 gtk/gtkprogressbar.c:126 gtk/gtkstatusicon.c:325 +#: gtk/gtkorientable.c:74 gtk/gtkprogressbar.c:126 gtk/gtkstatusicon.c:328 #: gtk/gtktrayicon-x11.c:110 msgid "Orientation" msgstr "" @@ -1296,7 +1324,7 @@ msgstr "" msgid "Marked up text to render" msgstr "" -#: gtk/gtkcellrenderertext.c:211 gtk/gtklabel.c:502 +#: gtk/gtkcellrenderertext.c:211 gtk/gtklabel.c:503 msgid "Attributes" msgstr "" @@ -1344,12 +1372,12 @@ msgstr "" msgid "Foreground color as a GdkColor" msgstr "" -#: gtk/gtkcellrenderertext.c:261 gtk/gtkentry.c:625 gtk/gtktexttag.c:251 -#: gtk/gtktextview.c:573 +#: gtk/gtkcellrenderertext.c:261 gtk/gtkentry.c:656 gtk/gtktexttag.c:251 +#: gtk/gtktextview.c:574 msgid "Editable" msgstr "" -#: gtk/gtkcellrenderertext.c:262 gtk/gtktexttag.c:252 gtk/gtktextview.c:574 +#: gtk/gtkcellrenderertext.c:262 gtk/gtktexttag.c:252 gtk/gtktextview.c:575 msgid "Whether the text can be modified by the user" msgstr "" @@ -1451,7 +1479,7 @@ msgid "" "probably don't need it" msgstr "" -#: gtk/gtkcellrenderertext.c:411 gtk/gtklabel.c:627 gtk/gtkprogressbar.c:206 +#: gtk/gtkcellrenderertext.c:411 gtk/gtklabel.c:628 gtk/gtkprogressbar.c:206 msgid "Ellipsize" msgstr "" @@ -1462,11 +1490,11 @@ msgid "" msgstr "" #: gtk/gtkcellrenderertext.c:431 gtk/gtkfilechooserbutton.c:421 -#: gtk/gtklabel.c:647 +#: gtk/gtklabel.c:648 msgid "Width In Characters" msgstr "" -#: gtk/gtkcellrenderertext.c:432 gtk/gtklabel.c:648 +#: gtk/gtkcellrenderertext.c:432 gtk/gtklabel.c:649 msgid "The desired width of the label, in characters" msgstr "" @@ -1480,7 +1508,7 @@ msgid "" "have enough room to display the entire string" msgstr "" -#: gtk/gtkcellrenderertext.c:470 gtk/gtkcombobox.c:678 +#: gtk/gtkcellrenderertext.c:470 gtk/gtkcombobox.c:680 msgid "Wrap width" msgstr "" @@ -1488,7 +1516,7 @@ msgstr "" msgid "The width at which the text is wrapped" msgstr "" -#: gtk/gtkcellrenderertext.c:491 gtk/gtktreeviewcolumn.c:297 +#: gtk/gtkcellrenderertext.c:491 gtk/gtktreeviewcolumn.c:298 msgid "Alignment" msgstr "" @@ -1685,7 +1713,7 @@ msgstr "" msgid "Spacing around check or radio indicator" msgstr "" -#: gtk/gtkcheckmenuitem.c:98 gtk/gtkmenu.c:500 gtk/gtktoggleaction.c:119 +#: gtk/gtkcheckmenuitem.c:98 gtk/gtkmenu.c:501 gtk/gtktoggleaction.c:119 #: gtk/gtktogglebutton.c:115 gtk/gtktoggletoolbutton.c:114 msgid "Active" msgstr "" @@ -1719,7 +1747,8 @@ msgid "Whether or not to give the color an alpha value" msgstr "" #: gtk/gtkcolorbutton.c:186 gtk/gtkfilechooserbutton.c:407 -#: gtk/gtkfontbutton.c:142 gtk/gtkprintjob.c:116 gtk/gtktreeviewcolumn.c:264 +#: gtk/gtkfontbutton.c:142 gtk/gtkprintjob.c:116 gtk/gtkstatusicon.c:424 +#: gtk/gtktreeviewcolumn.c:265 msgid "Title" msgstr "" @@ -1850,111 +1879,111 @@ msgstr "" msgid "Whether entered values must already be present in the list" msgstr "" -#: gtk/gtkcombobox.c:661 +#: gtk/gtkcombobox.c:663 msgid "ComboBox model" msgstr "" -#: gtk/gtkcombobox.c:662 +#: gtk/gtkcombobox.c:664 msgid "The model for the combo box" msgstr "" -#: gtk/gtkcombobox.c:679 +#: gtk/gtkcombobox.c:681 msgid "Wrap width for laying out the items in a grid" msgstr "" -#: gtk/gtkcombobox.c:701 +#: gtk/gtkcombobox.c:703 msgid "Row span column" msgstr "" -#: gtk/gtkcombobox.c:702 +#: gtk/gtkcombobox.c:704 msgid "TreeModel column containing the row span values" msgstr "" -#: gtk/gtkcombobox.c:723 +#: gtk/gtkcombobox.c:725 msgid "Column span column" msgstr "" -#: gtk/gtkcombobox.c:724 +#: gtk/gtkcombobox.c:726 msgid "TreeModel column containing the column span values" msgstr "" -#: gtk/gtkcombobox.c:745 +#: gtk/gtkcombobox.c:747 msgid "Active item" msgstr "" -#: gtk/gtkcombobox.c:746 +#: gtk/gtkcombobox.c:748 msgid "The item which is currently active" msgstr "" -#: gtk/gtkcombobox.c:765 gtk/gtkuimanager.c:222 +#: gtk/gtkcombobox.c:767 gtk/gtkuimanager.c:222 msgid "Add tearoffs to menus" msgstr "" -#: gtk/gtkcombobox.c:766 +#: gtk/gtkcombobox.c:768 msgid "Whether dropdowns should have a tearoff menu item" msgstr "" -#: gtk/gtkcombobox.c:781 gtk/gtkentry.c:650 +#: gtk/gtkcombobox.c:783 gtk/gtkentry.c:681 msgid "Has Frame" msgstr "" -#: gtk/gtkcombobox.c:782 +#: gtk/gtkcombobox.c:784 msgid "Whether the combo box draws a frame around the child" msgstr "" -#: gtk/gtkcombobox.c:790 +#: gtk/gtkcombobox.c:792 msgid "Whether the combo box grabs focus when it is clicked with the mouse" msgstr "" -#: gtk/gtkcombobox.c:805 gtk/gtkmenu.c:555 +#: gtk/gtkcombobox.c:807 gtk/gtkmenu.c:556 msgid "Tearoff Title" msgstr "" -#: gtk/gtkcombobox.c:806 +#: gtk/gtkcombobox.c:808 msgid "" "A title that may be displayed by the window manager when the popup is torn-" "off" msgstr "" -#: gtk/gtkcombobox.c:823 +#: gtk/gtkcombobox.c:825 msgid "Popup shown" msgstr "" -#: gtk/gtkcombobox.c:824 +#: gtk/gtkcombobox.c:826 msgid "Whether the combo's dropdown is shown" msgstr "" -#: gtk/gtkcombobox.c:840 +#: gtk/gtkcombobox.c:842 msgid "Button Sensitivity" msgstr "" -#: gtk/gtkcombobox.c:841 +#: gtk/gtkcombobox.c:843 msgid "Whether the dropdown button is sensitive when the model is empty" msgstr "" -#: gtk/gtkcombobox.c:848 +#: gtk/gtkcombobox.c:850 msgid "Appears as list" msgstr "" -#: gtk/gtkcombobox.c:849 +#: gtk/gtkcombobox.c:851 msgid "Whether dropdowns should look like lists rather than menus" msgstr "" -#: gtk/gtkcombobox.c:865 +#: gtk/gtkcombobox.c:867 msgid "Arrow Size" msgstr "" -#: gtk/gtkcombobox.c:866 +#: gtk/gtkcombobox.c:868 msgid "The minimum size of the arrow in the combo box" msgstr "" -#: gtk/gtkcombobox.c:881 gtk/gtkentry.c:750 gtk/gtkhandlebox.c:174 +#: gtk/gtkcombobox.c:883 gtk/gtkentry.c:781 gtk/gtkhandlebox.c:174 #: gtk/gtkmenubar.c:194 gtk/gtkstatusbar.c:186 gtk/gtktoolbar.c:623 #: gtk/gtkviewport.c:122 msgid "Shadow type" msgstr "" -#: gtk/gtkcombobox.c:882 +#: gtk/gtkcombobox.c:884 msgid "Which kind of shadow to draw around the combo box" msgstr "" @@ -2030,7 +2059,7 @@ msgstr "" msgid "The dialog has a separator bar above its buttons" msgstr "" -#: gtk/gtkdialog.c:191 +#: gtk/gtkdialog.c:191 gtk/gtkinfobar.c:439 msgid "Content area border" msgstr "" @@ -2038,7 +2067,7 @@ msgstr "" msgid "Width of border around the main dialog area" msgstr "" -#: gtk/gtkdialog.c:209 +#: gtk/gtkdialog.c:209 gtk/gtkinfobar.c:456 msgid "Content area spacing" msgstr "" @@ -2046,15 +2075,15 @@ msgstr "" msgid "Spacing between elements of the main dialog area" msgstr "" -#: gtk/gtkdialog.c:217 +#: gtk/gtkdialog.c:217 gtk/gtkinfobar.c:472 msgid "Button spacing" msgstr "" -#: gtk/gtkdialog.c:218 +#: gtk/gtkdialog.c:218 gtk/gtkinfobar.c:473 msgid "Spacing between buttons" msgstr "" -#: gtk/gtkdialog.c:226 +#: gtk/gtkdialog.c:226 gtk/gtkinfobar.c:488 msgid "Action area border" msgstr "" @@ -2062,359 +2091,376 @@ msgstr "" msgid "Width of border around the button area at the bottom of the dialog" msgstr "" -#: gtk/gtkentry.c:605 gtk/gtklabel.c:590 +#: gtk/gtkentry.c:628 +msgid "Text Buffer" +msgstr "" + +#: gtk/gtkentry.c:629 +msgid "Text buffer object which actually stores entry text" +msgstr "" + +#: gtk/gtkentry.c:636 gtk/gtklabel.c:591 msgid "Cursor Position" msgstr "" -#: gtk/gtkentry.c:606 gtk/gtklabel.c:591 +#: gtk/gtkentry.c:637 gtk/gtklabel.c:592 msgid "The current position of the insertion cursor in chars" msgstr "" -#: gtk/gtkentry.c:615 gtk/gtklabel.c:600 +#: gtk/gtkentry.c:646 gtk/gtklabel.c:601 msgid "Selection Bound" msgstr "" -#: gtk/gtkentry.c:616 gtk/gtklabel.c:601 +#: gtk/gtkentry.c:647 gtk/gtklabel.c:602 msgid "" "The position of the opposite end of the selection from the cursor in chars" msgstr "" -#: gtk/gtkentry.c:626 +#: gtk/gtkentry.c:657 msgid "Whether the entry contents can be edited" msgstr "" -#: gtk/gtkentry.c:633 +#: gtk/gtkentry.c:664 gtk/gtkentrybuffer.c:383 msgid "Maximum length" msgstr "" -#: gtk/gtkentry.c:634 +#: gtk/gtkentry.c:665 gtk/gtkentrybuffer.c:384 msgid "Maximum number of characters for this entry. Zero if no maximum" msgstr "" -#: gtk/gtkentry.c:642 +#: gtk/gtkentry.c:673 msgid "Visibility" msgstr "" -#: gtk/gtkentry.c:643 +#: gtk/gtkentry.c:674 msgid "" "FALSE displays the \"invisible char\" instead of the actual text (password " "mode)" msgstr "" -#: gtk/gtkentry.c:651 +#: gtk/gtkentry.c:682 msgid "FALSE removes outside bevel from entry" msgstr "" -#: gtk/gtkentry.c:659 +#: gtk/gtkentry.c:690 msgid "" "Border between text and frame. Overrides the inner-border style property" msgstr "" -#: gtk/gtkentry.c:666 gtk/gtkentry.c:1232 +#: gtk/gtkentry.c:697 gtk/gtkentry.c:1263 msgid "Invisible character" msgstr "" -#: gtk/gtkentry.c:667 gtk/gtkentry.c:1233 +#: gtk/gtkentry.c:698 gtk/gtkentry.c:1264 msgid "The character to use when masking entry contents (in \"password mode\")" msgstr "" -#: gtk/gtkentry.c:674 +#: gtk/gtkentry.c:705 msgid "Activates default" msgstr "" -#: gtk/gtkentry.c:675 +#: gtk/gtkentry.c:706 msgid "" "Whether to activate the default widget (such as the default button in a " "dialog) when Enter is pressed" msgstr "" -#: gtk/gtkentry.c:681 +#: gtk/gtkentry.c:712 msgid "Width in chars" msgstr "" -#: gtk/gtkentry.c:682 +#: gtk/gtkentry.c:713 msgid "Number of characters to leave space for in the entry" msgstr "" -#: gtk/gtkentry.c:691 +#: gtk/gtkentry.c:722 msgid "Scroll offset" msgstr "" -#: gtk/gtkentry.c:692 +#: gtk/gtkentry.c:723 msgid "Number of pixels of the entry scrolled off the screen to the left" msgstr "" -#: gtk/gtkentry.c:702 +#: gtk/gtkentry.c:733 msgid "The contents of the entry" msgstr "" -#: gtk/gtkentry.c:717 gtk/gtkmisc.c:73 +#: gtk/gtkentry.c:748 gtk/gtkmisc.c:73 msgid "X align" msgstr "" -#: gtk/gtkentry.c:718 gtk/gtkmisc.c:74 +#: gtk/gtkentry.c:749 gtk/gtkmisc.c:74 msgid "" "The horizontal alignment, from 0 (left) to 1 (right). Reversed for RTL " "layouts." msgstr "" -#: gtk/gtkentry.c:734 +#: gtk/gtkentry.c:765 msgid "Truncate multiline" msgstr "" -#: gtk/gtkentry.c:735 +#: gtk/gtkentry.c:766 msgid "Whether to truncate multiline pastes to one line." msgstr "" -#: gtk/gtkentry.c:751 +#: gtk/gtkentry.c:782 msgid "Which kind of shadow to draw around the entry when has-frame is set" msgstr "" -#: gtk/gtkentry.c:766 gtk/gtktextview.c:653 +#: gtk/gtkentry.c:797 gtk/gtktextview.c:654 msgid "Overwrite mode" msgstr "" -#: gtk/gtkentry.c:767 +#: gtk/gtkentry.c:798 msgid "Whether new text overwrites existing text" msgstr "" -#: gtk/gtkentry.c:781 +#: gtk/gtkentry.c:812 gtk/gtkentrybuffer.c:368 msgid "Text length" msgstr "" -#: gtk/gtkentry.c:782 +#: gtk/gtkentry.c:813 msgid "Length of the text currently in the entry" msgstr "" -#: gtk/gtkentry.c:797 +#: gtk/gtkentry.c:828 #, fuzzy msgid "Invisible char set" msgstr "Ungesíene" -#: gtk/gtkentry.c:798 +#: gtk/gtkentry.c:829 msgid "Whether the invisible char has been set" msgstr "" -#: gtk/gtkentry.c:816 +#: gtk/gtkentry.c:847 msgid "Caps Lock warning" msgstr "" -#: gtk/gtkentry.c:817 +#: gtk/gtkentry.c:848 msgid "Whether password entries will show a warning when Caps Lock is on" msgstr "" -#: gtk/gtkentry.c:831 +#: gtk/gtkentry.c:862 msgid "Progress Fraction" msgstr "" -#: gtk/gtkentry.c:832 +#: gtk/gtkentry.c:863 #, fuzzy msgid "The current fraction of the task that's been completed" msgstr "Þæt cynn þæs éagþyrles" -#: gtk/gtkentry.c:849 +#: gtk/gtkentry.c:880 msgid "Progress Pulse Step" msgstr "" -#: gtk/gtkentry.c:850 +#: gtk/gtkentry.c:881 msgid "" "The fraction of total entry width to move the progress bouncing block for " "each call to gtk_entry_progress_pulse()" msgstr "" -#: gtk/gtkentry.c:866 +#: gtk/gtkentry.c:897 msgid "Primary pixbuf" msgstr "" -#: gtk/gtkentry.c:867 +#: gtk/gtkentry.c:898 msgid "Primary pixbuf for the entry" msgstr "" -#: gtk/gtkentry.c:881 +#: gtk/gtkentry.c:912 msgid "Secondary pixbuf" msgstr "" -#: gtk/gtkentry.c:882 +#: gtk/gtkentry.c:913 msgid "Secondary pixbuf for the entry" msgstr "" -#: gtk/gtkentry.c:896 +#: gtk/gtkentry.c:927 msgid "Primary stock ID" msgstr "" -#: gtk/gtkentry.c:897 +#: gtk/gtkentry.c:928 msgid "Stock ID for primary icon" msgstr "" -#: gtk/gtkentry.c:911 +#: gtk/gtkentry.c:942 msgid "Secondary stock ID" msgstr "" -#: gtk/gtkentry.c:912 +#: gtk/gtkentry.c:943 msgid "Stock ID for secondary icon" msgstr "" -#: gtk/gtkentry.c:926 -#, fuzzy -msgid "Primary icon name" -msgstr "Segn" - -#: gtk/gtkentry.c:927 -msgid "Icon name for primary icon" -msgstr "" - -#: gtk/gtkentry.c:941 -msgid "Secondary icon name" -msgstr "" - -#: gtk/gtkentry.c:942 -msgid "Icon name for secondary icon" -msgstr "" - -#: gtk/gtkentry.c:956 -msgid "Primary GIcon" -msgstr "" - #: gtk/gtkentry.c:957 #, fuzzy -msgid "GIcon for primary icon" -msgstr "Segn þissum éagþyrle" +msgid "Primary icon name" +msgstr "Segn" -#: gtk/gtkentry.c:971 -msgid "Secondary GIcon" +#: gtk/gtkentry.c:958 +msgid "Icon name for primary icon" msgstr "" #: gtk/gtkentry.c:972 -msgid "GIcon for secondary icon" +msgid "Secondary icon name" msgstr "" -#: gtk/gtkentry.c:986 -msgid "Primary storage type" +#: gtk/gtkentry.c:973 +msgid "Icon name for secondary icon" msgstr "" #: gtk/gtkentry.c:987 -msgid "The representation being used for primary icon" +msgid "Primary GIcon" msgstr "" +#: gtk/gtkentry.c:988 +#, fuzzy +msgid "GIcon for primary icon" +msgstr "Segn þissum éagþyrle" + #: gtk/gtkentry.c:1002 -msgid "Secondary storage type" +msgid "Secondary GIcon" msgstr "" #: gtk/gtkentry.c:1003 +msgid "GIcon for secondary icon" +msgstr "" + +#: gtk/gtkentry.c:1017 +msgid "Primary storage type" +msgstr "" + +#: gtk/gtkentry.c:1018 +msgid "The representation being used for primary icon" +msgstr "" + +#: gtk/gtkentry.c:1033 +msgid "Secondary storage type" +msgstr "" + +#: gtk/gtkentry.c:1034 msgid "The representation being used for secondary icon" msgstr "" -#: gtk/gtkentry.c:1024 +#: gtk/gtkentry.c:1055 msgid "Primary icon activatable" msgstr "" -#: gtk/gtkentry.c:1025 +#: gtk/gtkentry.c:1056 msgid "Whether the primary icon is activatable" msgstr "" -#: gtk/gtkentry.c:1045 +#: gtk/gtkentry.c:1076 msgid "Secondary icon activatable" msgstr "" -#: gtk/gtkentry.c:1046 +#: gtk/gtkentry.c:1077 msgid "Whether the secondary icon is activatable" msgstr "" -#: gtk/gtkentry.c:1068 +#: gtk/gtkentry.c:1099 msgid "Primary icon sensitive" msgstr "" -#: gtk/gtkentry.c:1069 +#: gtk/gtkentry.c:1100 msgid "Whether the primary icon is sensitive" msgstr "" -#: gtk/gtkentry.c:1090 +#: gtk/gtkentry.c:1121 msgid "Secondary icon sensitive" msgstr "" -#: gtk/gtkentry.c:1091 +#: gtk/gtkentry.c:1122 msgid "Whether the secondary icon is sensitive" msgstr "" -#: gtk/gtkentry.c:1107 +#: gtk/gtkentry.c:1138 #, fuzzy msgid "Primary icon tooltip text" msgstr "Segn" -#: gtk/gtkentry.c:1108 gtk/gtkentry.c:1144 +#: gtk/gtkentry.c:1139 gtk/gtkentry.c:1175 msgid "The contents of the tooltip on the primary icon" msgstr "" -#: gtk/gtkentry.c:1124 +#: gtk/gtkentry.c:1155 msgid "Secondary icon tooltip text" msgstr "" -#: gtk/gtkentry.c:1125 gtk/gtkentry.c:1163 +#: gtk/gtkentry.c:1156 gtk/gtkentry.c:1194 msgid "The contents of the tooltip on the secondary icon" msgstr "" -#: gtk/gtkentry.c:1143 +#: gtk/gtkentry.c:1174 #, fuzzy msgid "Primary icon tooltip markup" msgstr "Segn" -#: gtk/gtkentry.c:1162 +#: gtk/gtkentry.c:1193 msgid "Secondary icon tooltip markup" msgstr "" -#: gtk/gtkentry.c:1182 gtk/gtktextview.c:681 +#: gtk/gtkentry.c:1213 gtk/gtktextview.c:682 msgid "IM module" msgstr "" -#: gtk/gtkentry.c:1183 gtk/gtktextview.c:682 +#: gtk/gtkentry.c:1214 gtk/gtktextview.c:683 msgid "Which IM module should be used" msgstr "" -#: gtk/gtkentry.c:1197 +#: gtk/gtkentry.c:1228 #, fuzzy msgid "Icon Prelight" msgstr "Híehþu" -#: gtk/gtkentry.c:1198 +#: gtk/gtkentry.c:1229 msgid "Whether activatable icons should prelight when hovered" msgstr "" -#: gtk/gtkentry.c:1211 +#: gtk/gtkentry.c:1242 msgid "Progress Border" msgstr "" -#: gtk/gtkentry.c:1212 +#: gtk/gtkentry.c:1243 msgid "Border around the progress bar" msgstr "" -#: gtk/gtkentry.c:1683 +#: gtk/gtkentry.c:1714 msgid "Border between text and frame." msgstr "" -#: gtk/gtkentry.c:1697 +#: gtk/gtkentry.c:1728 msgid "State Hint" msgstr "" -#: gtk/gtkentry.c:1698 +#: gtk/gtkentry.c:1729 msgid "Whether to pass a proper state when drawing shadow or background" msgstr "" -#: gtk/gtkentry.c:1703 gtk/gtklabel.c:830 +#: gtk/gtkentry.c:1734 gtk/gtklabel.c:848 msgid "Select on focus" msgstr "" -#: gtk/gtkentry.c:1704 +#: gtk/gtkentry.c:1735 msgid "Whether to select the contents of an entry when it is focused" msgstr "" -#: gtk/gtkentry.c:1718 +#: gtk/gtkentry.c:1749 msgid "Password Hint Timeout" msgstr "" -#: gtk/gtkentry.c:1719 +#: gtk/gtkentry.c:1750 msgid "How long to show the last input character in hidden entries" msgstr "" +#: gtk/gtkentrybuffer.c:354 +#, fuzzy +msgid "The contents of the buffer" +msgstr "Þæt cynn þæs éagþyrles" + +#: gtk/gtkentrybuffer.c:369 +msgid "Length of the text currently in the buffer" +msgstr "" + #: gtk/gtkentrycompletion.c:279 msgid "Completion Model" msgstr "" @@ -2431,7 +2477,7 @@ msgstr "" msgid "Minimum length of the search key in order to look up matches" msgstr "" -#: gtk/gtkentrycompletion.c:303 gtk/gtkiconview.c:585 +#: gtk/gtkentrycompletion.c:303 gtk/gtkiconview.c:586 msgid "Text column" msgstr "" @@ -2511,11 +2557,11 @@ msgstr "" msgid "Text of the expander's label" msgstr "" -#: gtk/gtkexpander.c:211 gtk/gtklabel.c:509 +#: gtk/gtkexpander.c:211 gtk/gtklabel.c:510 msgid "Use markup" msgstr "" -#: gtk/gtkexpander.c:212 gtk/gtklabel.c:510 +#: gtk/gtkexpander.c:212 gtk/gtklabel.c:511 msgid "The text of the label includes XML markup. See pango_parse_markup()" msgstr "" @@ -2531,11 +2577,11 @@ msgstr "" msgid "A widget to display in place of the usual expander label" msgstr "" -#: gtk/gtkexpander.c:236 gtk/gtktreeview.c:783 +#: gtk/gtkexpander.c:236 gtk/gtktreeview.c:774 msgid "Expander Size" msgstr "" -#: gtk/gtkexpander.c:237 gtk/gtktreeview.c:784 +#: gtk/gtkexpander.c:237 gtk/gtktreeview.c:775 msgid "Size of the expander arrow" msgstr "" @@ -2634,6 +2680,16 @@ msgid "" "dialog if necessary." msgstr "" +#: gtk/gtkfilechooser.c:283 +msgid "Allow folders creation" +msgstr "" + +#: gtk/gtkfilechooser.c:284 +msgid "" +"Whether a file chooser not in open mode will offer the user to create new " +"folders." +msgstr "" + #: gtk/gtkfilechooserbutton.c:376 msgid "Dialog" msgstr "" @@ -2651,7 +2707,7 @@ msgid "The desired width of the button widget, in characters." msgstr "" #: gtk/gtkfilesel.c:526 gtk/gtkimage.c:163 gtk/gtkrecentmanager.c:214 -#: gtk/gtkstatusicon.c:218 +#: gtk/gtkstatusicon.c:221 msgid "Filename" msgstr "" @@ -2825,86 +2881,86 @@ msgid "" "detached." msgstr "" -#: gtk/gtkiconview.c:548 +#: gtk/gtkiconview.c:549 msgid "Selection mode" msgstr "" -#: gtk/gtkiconview.c:549 +#: gtk/gtkiconview.c:550 #, fuzzy msgid "The selection mode" msgstr "Þæt gecorene géar" -#: gtk/gtkiconview.c:567 +#: gtk/gtkiconview.c:568 msgid "Pixbuf column" msgstr "" -#: gtk/gtkiconview.c:568 +#: gtk/gtkiconview.c:569 msgid "Model column used to retrieve the icon pixbuf from" msgstr "" -#: gtk/gtkiconview.c:586 +#: gtk/gtkiconview.c:587 msgid "Model column used to retrieve the text from" msgstr "" -#: gtk/gtkiconview.c:605 +#: gtk/gtkiconview.c:606 msgid "Markup column" msgstr "" -#: gtk/gtkiconview.c:606 +#: gtk/gtkiconview.c:607 msgid "Model column used to retrieve the text if using Pango markup" msgstr "" -#: gtk/gtkiconview.c:613 +#: gtk/gtkiconview.c:614 msgid "Icon View Model" msgstr "" -#: gtk/gtkiconview.c:614 +#: gtk/gtkiconview.c:615 #, fuzzy msgid "The model for the icon view" msgstr "Þæt cynn þæs éagþyrles" -#: gtk/gtkiconview.c:630 +#: gtk/gtkiconview.c:631 #, fuzzy msgid "Number of columns" msgstr "Gerím channela" -#: gtk/gtkiconview.c:631 +#: gtk/gtkiconview.c:632 msgid "Number of columns to display" msgstr "" -#: gtk/gtkiconview.c:648 +#: gtk/gtkiconview.c:649 msgid "Width for each item" msgstr "" -#: gtk/gtkiconview.c:649 +#: gtk/gtkiconview.c:650 msgid "The width used for each item" msgstr "" -#: gtk/gtkiconview.c:665 +#: gtk/gtkiconview.c:666 msgid "Space which is inserted between cells of an item" msgstr "" -#: gtk/gtkiconview.c:680 +#: gtk/gtkiconview.c:681 msgid "Row Spacing" msgstr "" -#: gtk/gtkiconview.c:681 +#: gtk/gtkiconview.c:682 msgid "Space which is inserted between grid rows" msgstr "" -#: gtk/gtkiconview.c:696 +#: gtk/gtkiconview.c:697 msgid "Column Spacing" msgstr "" -#: gtk/gtkiconview.c:697 +#: gtk/gtkiconview.c:698 msgid "Space which is inserted between grid columns" msgstr "" -#: gtk/gtkiconview.c:712 +#: gtk/gtkiconview.c:713 msgid "Margin" msgstr "" -#: gtk/gtkiconview.c:713 +#: gtk/gtkiconview.c:714 msgid "Space which is inserted at the edges of the icon view" msgstr "" @@ -2913,15 +2969,15 @@ msgid "" "How the text and icon of each item are positioned relative to each other" msgstr "" -#: gtk/gtkiconview.c:746 gtk/gtktreeview.c:618 gtk/gtktreeviewcolumn.c:307 +#: gtk/gtkiconview.c:746 gtk/gtktreeview.c:609 gtk/gtktreeviewcolumn.c:308 msgid "Reorderable" msgstr "" -#: gtk/gtkiconview.c:747 gtk/gtktreeview.c:619 +#: gtk/gtkiconview.c:747 gtk/gtktreeview.c:610 msgid "View is reorderable" msgstr "" -#: gtk/gtkiconview.c:754 gtk/gtktreeview.c:769 +#: gtk/gtkiconview.c:754 gtk/gtktreeview.c:760 msgid "Tooltip Column" msgstr "" @@ -2929,27 +2985,35 @@ msgstr "" msgid "The column in the model containing the tooltip texts for the items" msgstr "" -#: gtk/gtkiconview.c:766 -msgid "Selection Box Color" -msgstr "" - -#: gtk/gtkiconview.c:767 -msgid "Color of the selection box" +#: gtk/gtkiconview.c:772 +msgid "Item Padding" msgstr "" #: gtk/gtkiconview.c:773 +msgid "Padding around icon view items" +msgstr "" + +#: gtk/gtkiconview.c:782 +msgid "Selection Box Color" +msgstr "" + +#: gtk/gtkiconview.c:783 +msgid "Color of the selection box" +msgstr "" + +#: gtk/gtkiconview.c:789 msgid "Selection Box Alpha" msgstr "" -#: gtk/gtkiconview.c:774 +#: gtk/gtkiconview.c:790 msgid "Opacity of the selection box" msgstr "" -#: gtk/gtkimage.c:131 gtk/gtkstatusicon.c:210 +#: gtk/gtkimage.c:131 gtk/gtkstatusicon.c:213 msgid "Pixbuf" msgstr "" -#: gtk/gtkimage.c:132 gtk/gtkstatusicon.c:211 +#: gtk/gtkimage.c:132 gtk/gtkstatusicon.c:214 msgid "A GdkPixbuf to display" msgstr "" @@ -2977,11 +3041,11 @@ msgstr "" msgid "Mask bitmap to use with GdkImage or GdkPixmap" msgstr "" -#: gtk/gtkimage.c:164 gtk/gtkstatusicon.c:219 +#: gtk/gtkimage.c:164 gtk/gtkstatusicon.c:222 msgid "Filename to load and display" msgstr "" -#: gtk/gtkimage.c:173 gtk/gtkstatusicon.c:227 +#: gtk/gtkimage.c:173 gtk/gtkstatusicon.c:230 msgid "Stock ID for a stock image to display" msgstr "" @@ -3017,11 +3081,11 @@ msgstr "" msgid "GdkPixbufAnimation to display" msgstr "" -#: gtk/gtkimage.c:255 gtk/gtkstatusicon.c:258 +#: gtk/gtkimage.c:255 gtk/gtkstatusicon.c:261 msgid "Storage type" msgstr "" -#: gtk/gtkimage.c:256 gtk/gtkstatusicon.c:259 +#: gtk/gtkimage.c:256 gtk/gtkstatusicon.c:262 msgid "The representation being used for image data" msgstr "" @@ -3041,7 +3105,7 @@ msgstr "" msgid "Whether the image will always be shown" msgstr "" -#: gtk/gtkimagemenuitem.c:184 gtk/gtkmenu.c:515 +#: gtk/gtkimagemenuitem.c:184 gtk/gtkmenu.c:516 msgid "Accel Group" msgstr "" @@ -3057,110 +3121,138 @@ msgstr "" msgid "Whether images should be shown in menus" msgstr "" +#: gtk/gtkinfobar.c:384 gtk/gtkmessagedialog.c:128 +msgid "Message Type" +msgstr "" + +#: gtk/gtkinfobar.c:385 gtk/gtkmessagedialog.c:129 +msgid "The type of message" +msgstr "" + +#: gtk/gtkinfobar.c:440 +msgid "Width of border around the content area" +msgstr "" + +#: gtk/gtkinfobar.c:457 +msgid "Spacing between elements of the area" +msgstr "" + +#: gtk/gtkinfobar.c:489 +msgid "Width of border around the action area" +msgstr "" + #: gtk/gtkinvisible.c:87 gtk/gtkwindow.c:615 msgid "The screen where this window will be displayed" msgstr "" -#: gtk/gtklabel.c:496 +#: gtk/gtklabel.c:497 msgid "The text of the label" msgstr "" -#: gtk/gtklabel.c:503 +#: gtk/gtklabel.c:504 msgid "A list of style attributes to apply to the text of the label" msgstr "" -#: gtk/gtklabel.c:524 gtk/gtktexttag.c:359 gtk/gtktextview.c:590 +#: gtk/gtklabel.c:525 gtk/gtktexttag.c:359 gtk/gtktextview.c:591 msgid "Justification" msgstr "" -#: gtk/gtklabel.c:525 +#: gtk/gtklabel.c:526 msgid "" "The alignment of the lines in the text of the label relative to each other. " "This does NOT affect the alignment of the label within its allocation. See " "GtkMisc::xalign for that" msgstr "" -#: gtk/gtklabel.c:533 +#: gtk/gtklabel.c:534 msgid "Pattern" msgstr "" -#: gtk/gtklabel.c:534 +#: gtk/gtklabel.c:535 msgid "" "A string with _ characters in positions correspond to characters in the text " "to underline" msgstr "" -#: gtk/gtklabel.c:541 +#: gtk/gtklabel.c:542 msgid "Line wrap" msgstr "" -#: gtk/gtklabel.c:542 +#: gtk/gtklabel.c:543 msgid "If set, wrap lines if the text becomes too wide" msgstr "" -#: gtk/gtklabel.c:557 +#: gtk/gtklabel.c:558 msgid "Line wrap mode" msgstr "" -#: gtk/gtklabel.c:558 +#: gtk/gtklabel.c:559 msgid "If wrap is set, controls how linewrapping is done" msgstr "" -#: gtk/gtklabel.c:565 +#: gtk/gtklabel.c:566 msgid "Selectable" msgstr "" -#: gtk/gtklabel.c:566 +#: gtk/gtklabel.c:567 msgid "Whether the label text can be selected with the mouse" msgstr "" -#: gtk/gtklabel.c:572 +#: gtk/gtklabel.c:573 msgid "Mnemonic key" msgstr "" -#: gtk/gtklabel.c:573 +#: gtk/gtklabel.c:574 msgid "The mnemonic accelerator key for this label" msgstr "" -#: gtk/gtklabel.c:581 +#: gtk/gtklabel.c:582 msgid "Mnemonic widget" msgstr "" -#: gtk/gtklabel.c:582 +#: gtk/gtklabel.c:583 msgid "The widget to be activated when the label's mnemonic key is pressed" msgstr "" -#: gtk/gtklabel.c:628 +#: gtk/gtklabel.c:629 msgid "" "The preferred place to ellipsize the string, if the label does not have " "enough room to display the entire string" msgstr "" -#: gtk/gtklabel.c:668 +#: gtk/gtklabel.c:669 msgid "Single Line Mode" msgstr "" -#: gtk/gtklabel.c:669 +#: gtk/gtklabel.c:670 msgid "Whether the label is in single line mode" msgstr "" -#: gtk/gtklabel.c:686 +#: gtk/gtklabel.c:687 msgid "Angle" msgstr "" -#: gtk/gtklabel.c:687 +#: gtk/gtklabel.c:688 msgid "Angle at which the label is rotated" msgstr "" -#: gtk/gtklabel.c:707 +#: gtk/gtklabel.c:708 msgid "Maximum Width In Characters" msgstr "" -#: gtk/gtklabel.c:708 +#: gtk/gtklabel.c:709 msgid "The desired maximum width of the label, in characters" msgstr "" -#: gtk/gtklabel.c:831 +#: gtk/gtklabel.c:727 +msgid "Track visited links" +msgstr "" + +#: gtk/gtklabel.c:728 +msgid "Whether visited links should be tracked" +msgstr "" + +#: gtk/gtklabel.c:849 msgid "Whether to select the contents of a selectable label when it is focused" msgstr "" @@ -3204,164 +3296,174 @@ msgstr "" msgid "Whether this link has been visited." msgstr "" -#: gtk/gtkmenu.c:501 +#: gtk/gtkmenu.c:502 msgid "The currently selected menu item" msgstr "" -#: gtk/gtkmenu.c:516 +#: gtk/gtkmenu.c:517 msgid "The accel group holding accelerators for the menu" msgstr "" -#: gtk/gtkmenu.c:530 gtk/gtkmenuitem.c:285 +#: gtk/gtkmenu.c:531 gtk/gtkmenuitem.c:290 msgid "Accel Path" msgstr "" -#: gtk/gtkmenu.c:531 +#: gtk/gtkmenu.c:532 msgid "An accel path used to conveniently construct accel paths of child items" msgstr "" -#: gtk/gtkmenu.c:547 +#: gtk/gtkmenu.c:548 msgid "Attach Widget" msgstr "" -#: gtk/gtkmenu.c:548 +#: gtk/gtkmenu.c:549 msgid "The widget the menu is attached to" msgstr "" -#: gtk/gtkmenu.c:556 +#: gtk/gtkmenu.c:557 msgid "" "A title that may be displayed by the window manager when this menu is torn-" "off" msgstr "" -#: gtk/gtkmenu.c:570 +#: gtk/gtkmenu.c:571 msgid "Tearoff State" msgstr "" -#: gtk/gtkmenu.c:571 +#: gtk/gtkmenu.c:572 msgid "A boolean that indicates whether the menu is torn-off" msgstr "" -#: gtk/gtkmenu.c:585 +#: gtk/gtkmenu.c:586 #, fuzzy msgid "Monitor" msgstr "Mónaþ" -#: gtk/gtkmenu.c:586 +#: gtk/gtkmenu.c:587 msgid "The monitor the menu will be popped up on" msgstr "" -#: gtk/gtkmenu.c:592 +#: gtk/gtkmenu.c:593 msgid "Vertical Padding" msgstr "" -#: gtk/gtkmenu.c:593 +#: gtk/gtkmenu.c:594 msgid "Extra space at the top and bottom of the menu" msgstr "" -#: gtk/gtkmenu.c:601 +#: gtk/gtkmenu.c:616 +msgid "Reserve Toggle Size" +msgstr "" + +#: gtk/gtkmenu.c:617 +msgid "" +"A boolean that indicates whether the menu reserves space for toggles and " +"icons" +msgstr "" + +#: gtk/gtkmenu.c:623 msgid "Horizontal Padding" msgstr "" -#: gtk/gtkmenu.c:602 +#: gtk/gtkmenu.c:624 msgid "Extra space at the left and right edges of the menu" msgstr "" -#: gtk/gtkmenu.c:610 +#: gtk/gtkmenu.c:632 msgid "Vertical Offset" msgstr "" -#: gtk/gtkmenu.c:611 +#: gtk/gtkmenu.c:633 msgid "" "When the menu is a submenu, position it this number of pixels offset " "vertically" msgstr "" -#: gtk/gtkmenu.c:619 +#: gtk/gtkmenu.c:641 msgid "Horizontal Offset" msgstr "" -#: gtk/gtkmenu.c:620 +#: gtk/gtkmenu.c:642 msgid "" "When the menu is a submenu, position it this number of pixels offset " "horizontally" msgstr "" -#: gtk/gtkmenu.c:628 +#: gtk/gtkmenu.c:650 msgid "Double Arrows" msgstr "" -#: gtk/gtkmenu.c:629 +#: gtk/gtkmenu.c:651 msgid "When scrolling, always show both arrows." msgstr "" -#: gtk/gtkmenu.c:642 +#: gtk/gtkmenu.c:664 msgid "Arrow Placement" msgstr "" -#: gtk/gtkmenu.c:643 +#: gtk/gtkmenu.c:665 msgid "Indicates where scroll arrows should be placed" msgstr "" -#: gtk/gtkmenu.c:651 +#: gtk/gtkmenu.c:673 msgid "Left Attach" msgstr "" -#: gtk/gtkmenu.c:652 gtk/gtktable.c:174 +#: gtk/gtkmenu.c:674 gtk/gtktable.c:174 msgid "The column number to attach the left side of the child to" msgstr "" -#: gtk/gtkmenu.c:659 +#: gtk/gtkmenu.c:681 msgid "Right Attach" msgstr "" -#: gtk/gtkmenu.c:660 +#: gtk/gtkmenu.c:682 msgid "The column number to attach the right side of the child to" msgstr "" -#: gtk/gtkmenu.c:667 +#: gtk/gtkmenu.c:689 msgid "Top Attach" msgstr "" -#: gtk/gtkmenu.c:668 +#: gtk/gtkmenu.c:690 msgid "The row number to attach the top of the child to" msgstr "" -#: gtk/gtkmenu.c:675 +#: gtk/gtkmenu.c:697 msgid "Bottom Attach" msgstr "" -#: gtk/gtkmenu.c:676 gtk/gtktable.c:195 +#: gtk/gtkmenu.c:698 gtk/gtktable.c:195 msgid "The row number to attach the bottom of the child to" msgstr "" -#: gtk/gtkmenu.c:690 +#: gtk/gtkmenu.c:712 msgid "Arbitrary constant to scale down the size of the scroll arrow" msgstr "" -#: gtk/gtkmenu.c:777 +#: gtk/gtkmenu.c:799 msgid "Can change accelerators" msgstr "" -#: gtk/gtkmenu.c:778 +#: gtk/gtkmenu.c:800 msgid "" "Whether menu accelerators can be changed by pressing a key over the menu item" msgstr "" -#: gtk/gtkmenu.c:783 +#: gtk/gtkmenu.c:805 msgid "Delay before submenus appear" msgstr "" -#: gtk/gtkmenu.c:784 +#: gtk/gtkmenu.c:806 msgid "" "Minimum time the pointer must stay over a menu item before the submenu appear" msgstr "" -#: gtk/gtkmenu.c:791 +#: gtk/gtkmenu.c:813 msgid "Delay before hiding a submenu" msgstr "" -#: gtk/gtkmenu.c:792 +#: gtk/gtkmenu.c:814 msgid "" "The time before hiding a submenu when the pointer is moving towards the " "submenu" @@ -3403,41 +3505,41 @@ msgstr "" msgid "Delay before the submenus of a menu bar appear" msgstr "" -#: gtk/gtkmenuitem.c:252 +#: gtk/gtkmenuitem.c:257 msgid "Right Justified" msgstr "" -#: gtk/gtkmenuitem.c:253 +#: gtk/gtkmenuitem.c:258 msgid "" "Sets whether the menu item appears justified at the right side of a menu bar" msgstr "" -#: gtk/gtkmenuitem.c:267 +#: gtk/gtkmenuitem.c:272 msgid "Submenu" msgstr "" -#: gtk/gtkmenuitem.c:268 +#: gtk/gtkmenuitem.c:273 msgid "The submenu attached to the menu item, or NULL if it has none" msgstr "" -#: gtk/gtkmenuitem.c:286 +#: gtk/gtkmenuitem.c:291 msgid "Sets the accelerator path of the menu item" msgstr "" -#: gtk/gtkmenuitem.c:301 +#: gtk/gtkmenuitem.c:306 #, fuzzy msgid "The text for the child label" msgstr "Þæt cynn þæs éagþyrles" -#: gtk/gtkmenuitem.c:364 +#: gtk/gtkmenuitem.c:369 msgid "Amount of space used up by arrow, relative to the menu item's font size" msgstr "" -#: gtk/gtkmenuitem.c:377 +#: gtk/gtkmenuitem.c:382 msgid "Width in Characters" msgstr "" -#: gtk/gtkmenuitem.c:378 +#: gtk/gtkmenuitem.c:383 msgid "The minimum desired width of the menu item in characters" msgstr "" @@ -3474,14 +3576,6 @@ msgid "" "Whether to put a separator between the message dialog's text and the buttons" msgstr "" -#: gtk/gtkmessagedialog.c:128 -msgid "Message Type" -msgstr "" - -#: gtk/gtkmessagedialog.c:129 -msgid "The type of message" -msgstr "" - #: gtk/gtkmessagedialog.c:136 msgid "Message Buttons" msgstr "" @@ -3549,24 +3643,24 @@ msgid "" "The amount of space to add on the top and bottom of the widget, in pixels" msgstr "" -#: gtk/gtkmountoperation.c:139 +#: gtk/gtkmountoperation.c:160 msgid "Parent" msgstr "" -#: gtk/gtkmountoperation.c:140 +#: gtk/gtkmountoperation.c:161 #, fuzzy msgid "The parent window" msgstr "Þæt cynn þæs éagþyrles" -#: gtk/gtkmountoperation.c:147 +#: gtk/gtkmountoperation.c:168 msgid "Is Showing" msgstr "" -#: gtk/gtkmountoperation.c:148 +#: gtk/gtkmountoperation.c:169 msgid "Are we showing a dialog" msgstr "" -#: gtk/gtkmountoperation.c:156 +#: gtk/gtkmountoperation.c:177 msgid "The screen where this window will be displayed." msgstr "" @@ -3853,7 +3947,7 @@ msgstr "" msgid "If TRUE, the child can be made smaller than its requisition" msgstr "" -#: gtk/gtkplug.c:150 gtk/gtkstatusicon.c:309 +#: gtk/gtkplug.c:150 gtk/gtkstatusicon.c:312 msgid "Embedded" msgstr "" @@ -3985,11 +4079,11 @@ msgstr "" msgid "Printer settings" msgstr "" -#: gtk/gtkprintjob.c:143 gtk/gtkprintjob.c:144 gtk/gtkprintunixdialog.c:266 +#: gtk/gtkprintjob.c:143 gtk/gtkprintjob.c:144 gtk/gtkprintunixdialog.c:302 msgid "Page Setup" msgstr "" -#: gtk/gtkprintjob.c:152 gtk/gtkprintoperation.c:1056 +#: gtk/gtkprintjob.c:152 gtk/gtkprintoperation.c:1082 msgid "Track Print Status" msgstr "" @@ -3999,162 +4093,184 @@ msgid "" "print data has been sent to the printer or print server." msgstr "" -#: gtk/gtkprintoperation.c:928 +#: gtk/gtkprintoperation.c:954 msgid "Default Page Setup" msgstr "" -#: gtk/gtkprintoperation.c:929 +#: gtk/gtkprintoperation.c:955 msgid "The GtkPageSetup used by default" msgstr "" -#: gtk/gtkprintoperation.c:947 gtk/gtkprintunixdialog.c:284 +#: gtk/gtkprintoperation.c:973 gtk/gtkprintunixdialog.c:320 msgid "Print Settings" msgstr "" -#: gtk/gtkprintoperation.c:948 gtk/gtkprintunixdialog.c:285 +#: gtk/gtkprintoperation.c:974 gtk/gtkprintunixdialog.c:321 msgid "The GtkPrintSettings used for initializing the dialog" msgstr "" -#: gtk/gtkprintoperation.c:966 +#: gtk/gtkprintoperation.c:992 #, fuzzy msgid "Job Name" msgstr "Nama" -#: gtk/gtkprintoperation.c:967 +#: gtk/gtkprintoperation.c:993 msgid "A string used for identifying the print job." msgstr "" -#: gtk/gtkprintoperation.c:991 +#: gtk/gtkprintoperation.c:1017 #, fuzzy msgid "Number of Pages" msgstr "Gerím channela" -#: gtk/gtkprintoperation.c:992 +#: gtk/gtkprintoperation.c:1018 #, fuzzy msgid "The number of pages in the document." msgstr "Þæt gerím rǽwa þæs pixbuf" -#: gtk/gtkprintoperation.c:1013 gtk/gtkprintunixdialog.c:274 +#: gtk/gtkprintoperation.c:1039 gtk/gtkprintunixdialog.c:310 msgid "Current Page" msgstr "" -#: gtk/gtkprintoperation.c:1014 gtk/gtkprintunixdialog.c:275 +#: gtk/gtkprintoperation.c:1040 gtk/gtkprintunixdialog.c:311 msgid "The current page in the document" msgstr "" -#: gtk/gtkprintoperation.c:1035 +#: gtk/gtkprintoperation.c:1061 msgid "Use full page" msgstr "" -#: gtk/gtkprintoperation.c:1036 +#: gtk/gtkprintoperation.c:1062 msgid "" "TRUE if the origin of the context should be at the corner of the page and " "not the corner of the imageable area" msgstr "" -#: gtk/gtkprintoperation.c:1057 +#: gtk/gtkprintoperation.c:1083 msgid "" "TRUE if the print operation will continue to report on the print job status " "after the print data has been sent to the printer or print server." msgstr "" -#: gtk/gtkprintoperation.c:1074 +#: gtk/gtkprintoperation.c:1100 msgid "Unit" msgstr "" -#: gtk/gtkprintoperation.c:1075 +#: gtk/gtkprintoperation.c:1101 msgid "The unit in which distances can be measured in the context" msgstr "" -#: gtk/gtkprintoperation.c:1092 +#: gtk/gtkprintoperation.c:1118 msgid "Show Dialog" msgstr "" -#: gtk/gtkprintoperation.c:1093 +#: gtk/gtkprintoperation.c:1119 msgid "TRUE if a progress dialog is shown while printing." msgstr "" -#: gtk/gtkprintoperation.c:1116 +#: gtk/gtkprintoperation.c:1142 msgid "Allow Async" msgstr "" -#: gtk/gtkprintoperation.c:1117 +#: gtk/gtkprintoperation.c:1143 msgid "TRUE if print process may run asynchronous." msgstr "" -#: gtk/gtkprintoperation.c:1139 gtk/gtkprintoperation.c:1140 +#: gtk/gtkprintoperation.c:1165 gtk/gtkprintoperation.c:1166 msgid "Export filename" msgstr "" -#: gtk/gtkprintoperation.c:1154 +#: gtk/gtkprintoperation.c:1180 msgid "Status" msgstr "" -#: gtk/gtkprintoperation.c:1155 +#: gtk/gtkprintoperation.c:1181 msgid "The status of the print operation" msgstr "" -#: gtk/gtkprintoperation.c:1175 +#: gtk/gtkprintoperation.c:1201 msgid "Status String" msgstr "" -#: gtk/gtkprintoperation.c:1176 +#: gtk/gtkprintoperation.c:1202 msgid "A human-readable description of the status" msgstr "" -#: gtk/gtkprintoperation.c:1194 +#: gtk/gtkprintoperation.c:1220 msgid "Custom tab label" msgstr "" -#: gtk/gtkprintoperation.c:1195 +#: gtk/gtkprintoperation.c:1221 msgid "Label for the tab containing custom widgets." msgstr "" -#: gtk/gtkprintoperation.c:1210 gtk/gtkprintunixdialog.c:309 +#: gtk/gtkprintoperation.c:1236 gtk/gtkprintunixdialog.c:345 msgid "Support Selection" msgstr "" -#: gtk/gtkprintoperation.c:1211 +#: gtk/gtkprintoperation.c:1237 msgid "TRUE if the print operation will support print of selection." msgstr "" -#: gtk/gtkprintoperation.c:1227 gtk/gtkprintunixdialog.c:317 +#: gtk/gtkprintoperation.c:1253 gtk/gtkprintunixdialog.c:353 msgid "Has Selection" msgstr "" -#: gtk/gtkprintoperation.c:1228 +#: gtk/gtkprintoperation.c:1254 msgid "TRUE if a selecion exists." msgstr "" -#: gtk/gtkprintunixdialog.c:267 +#: gtk/gtkprintoperation.c:1269 gtk/gtkprintunixdialog.c:361 +msgid "Embed Page Setup" +msgstr "" + +#: gtk/gtkprintoperation.c:1270 +msgid "TRUE if page setup combos are embedded in GtkPrintDialog" +msgstr "" + +#: gtk/gtkprintoperation.c:1291 +#, fuzzy +msgid "Number of Pages To Print" +msgstr "Gerím channela" + +#: gtk/gtkprintoperation.c:1292 +#, fuzzy +msgid "The number of pages that will be printed." +msgstr "Þæt gerím rǽwa þæs pixbuf" + +#: gtk/gtkprintunixdialog.c:303 msgid "The GtkPageSetup to use" msgstr "" -#: gtk/gtkprintunixdialog.c:292 +#: gtk/gtkprintunixdialog.c:328 #, fuzzy msgid "Selected Printer" msgstr "Þæt gecorene géar" -#: gtk/gtkprintunixdialog.c:293 +#: gtk/gtkprintunixdialog.c:329 msgid "The GtkPrinter which is selected" msgstr "" -#: gtk/gtkprintunixdialog.c:300 +#: gtk/gtkprintunixdialog.c:336 msgid "Manual Capabilites" msgstr "" -#: gtk/gtkprintunixdialog.c:301 +#: gtk/gtkprintunixdialog.c:337 msgid "Capabilities the application can handle" msgstr "" -#: gtk/gtkprintunixdialog.c:310 +#: gtk/gtkprintunixdialog.c:346 msgid "Whether the dialog supports selection" msgstr "" -#: gtk/gtkprintunixdialog.c:318 +#: gtk/gtkprintunixdialog.c:354 msgid "Whether the application has a selection" msgstr "" +#: gtk/gtkprintunixdialog.c:362 +msgid "TRUE if page setup combos are embedded in GtkPrintUnixDialog" +msgstr "" + #: gtk/gtkprogress.c:102 msgid "Activity mode" msgstr "" @@ -4691,11 +4807,11 @@ msgid "" "Display a second forward arrow button on the opposite end of the scrollbar" msgstr "" -#: gtk/gtkscrolledwindow.c:218 gtk/gtktext.c:545 gtk/gtktreeview.c:578 +#: gtk/gtkscrolledwindow.c:218 gtk/gtktext.c:545 gtk/gtktreeview.c:569 msgid "Horizontal Adjustment" msgstr "" -#: gtk/gtkscrolledwindow.c:225 gtk/gtktext.c:553 gtk/gtktreeview.c:586 +#: gtk/gtkscrolledwindow.c:225 gtk/gtktext.c:553 gtk/gtktreeview.c:577 msgid "Vertical Adjustment" msgstr "" @@ -5210,21 +5326,21 @@ msgstr "Hæfþ Alpha" msgid "Whether tooltips should be shown on widgets" msgstr "" -#: gtk/gtksizegroup.c:293 +#: gtk/gtksizegroup.c:301 msgid "Mode" msgstr "" -#: gtk/gtksizegroup.c:294 +#: gtk/gtksizegroup.c:302 msgid "" "The directions in which the size group affects the requested sizes of its " "component widgets" msgstr "" -#: gtk/gtksizegroup.c:310 +#: gtk/gtksizegroup.c:318 msgid "Ignore hidden" msgstr "" -#: gtk/gtksizegroup.c:311 +#: gtk/gtksizegroup.c:319 msgid "" "If TRUE, unmapped widgets are ignored when determining the size of the group" msgstr "" @@ -5292,60 +5408,65 @@ msgstr "" msgid "Style of bevel around the statusbar text" msgstr "" -#: gtk/gtkstatusicon.c:268 +#: gtk/gtkstatusicon.c:271 #, fuzzy msgid "The size of the icon" msgstr "Þæt cynn þæs éagþyrles" -#: gtk/gtkstatusicon.c:278 +#: gtk/gtkstatusicon.c:281 msgid "The screen where this status icon will be displayed" msgstr "" -#: gtk/gtkstatusicon.c:285 +#: gtk/gtkstatusicon.c:288 msgid "Blinking" msgstr "" -#: gtk/gtkstatusicon.c:286 +#: gtk/gtkstatusicon.c:289 msgid "Whether or not the status icon is blinking" msgstr "" -#: gtk/gtkstatusicon.c:294 +#: gtk/gtkstatusicon.c:297 msgid "Whether or not the status icon is visible" msgstr "" -#: gtk/gtkstatusicon.c:310 +#: gtk/gtkstatusicon.c:313 msgid "Whether or not the status icon is embedded" msgstr "" -#: gtk/gtkstatusicon.c:326 gtk/gtktrayicon-x11.c:111 +#: gtk/gtkstatusicon.c:329 gtk/gtktrayicon-x11.c:111 msgid "The orientation of the tray" msgstr "" -#: gtk/gtkstatusicon.c:353 gtk/gtkwidget.c:632 +#: gtk/gtkstatusicon.c:356 gtk/gtkwidget.c:634 #, fuzzy msgid "Has tooltip" msgstr "Hæfþ Alpha" -#: gtk/gtkstatusicon.c:354 +#: gtk/gtkstatusicon.c:357 msgid "Whether this tray icon has a tooltip" msgstr "" -#: gtk/gtkstatusicon.c:375 gtk/gtkwidget.c:653 +#: gtk/gtkstatusicon.c:382 gtk/gtkwidget.c:655 msgid "Tooltip Text" msgstr "" -#: gtk/gtkstatusicon.c:376 gtk/gtkwidget.c:654 gtk/gtkwidget.c:675 +#: gtk/gtkstatusicon.c:383 gtk/gtkwidget.c:656 gtk/gtkwidget.c:677 msgid "The contents of the tooltip for this widget" msgstr "" -#: gtk/gtkstatusicon.c:399 gtk/gtkwidget.c:674 +#: gtk/gtkstatusicon.c:406 gtk/gtkwidget.c:676 msgid "Tooltip markup" msgstr "" -#: gtk/gtkstatusicon.c:400 +#: gtk/gtkstatusicon.c:407 msgid "The contents of the tooltip for this tray icon" msgstr "" +#: gtk/gtkstatusicon.c:425 +#, fuzzy +msgid "The title of this tray icon" +msgstr "Þæt cynn þæs éagþyrles" + #: gtk/gtktable.c:129 msgid "Rows" msgstr "" @@ -5605,7 +5726,7 @@ msgid "" "such as PANGO_SCALE_X_LARGE" msgstr "" -#: gtk/gtktexttag.c:360 gtk/gtktextview.c:591 +#: gtk/gtktexttag.c:360 gtk/gtktextview.c:592 msgid "Left, right, or center justification" msgstr "" @@ -5619,7 +5740,7 @@ msgstr "" msgid "Left margin" msgstr "" -#: gtk/gtktexttag.c:387 gtk/gtktextview.c:600 +#: gtk/gtktexttag.c:387 gtk/gtktextview.c:601 msgid "Width of the left margin in pixels" msgstr "" @@ -5627,15 +5748,15 @@ msgstr "" msgid "Right margin" msgstr "" -#: gtk/gtktexttag.c:397 gtk/gtktextview.c:610 +#: gtk/gtktexttag.c:397 gtk/gtktextview.c:611 msgid "Width of the right margin in pixels" msgstr "" -#: gtk/gtktexttag.c:407 gtk/gtktextview.c:619 +#: gtk/gtktexttag.c:407 gtk/gtktextview.c:620 msgid "Indent" msgstr "" -#: gtk/gtktexttag.c:408 gtk/gtktextview.c:620 +#: gtk/gtktexttag.c:408 gtk/gtktextview.c:621 msgid "Amount to indent the paragraph, in pixels" msgstr "" @@ -5649,7 +5770,7 @@ msgstr "" msgid "Pixels above lines" msgstr "" -#: gtk/gtktexttag.c:429 gtk/gtktextview.c:544 +#: gtk/gtktexttag.c:429 gtk/gtktextview.c:545 msgid "Pixels of blank space above paragraphs" msgstr "" @@ -5657,7 +5778,7 @@ msgstr "" msgid "Pixels below lines" msgstr "" -#: gtk/gtktexttag.c:439 gtk/gtktextview.c:554 +#: gtk/gtktexttag.c:439 gtk/gtktextview.c:555 msgid "Pixels of blank space below paragraphs" msgstr "" @@ -5665,20 +5786,20 @@ msgstr "" msgid "Pixels inside wrap" msgstr "" -#: gtk/gtktexttag.c:449 gtk/gtktextview.c:564 +#: gtk/gtktexttag.c:449 gtk/gtktextview.c:565 msgid "Pixels of blank space between wrapped lines in a paragraph" msgstr "" -#: gtk/gtktexttag.c:476 gtk/gtktextview.c:582 +#: gtk/gtktexttag.c:476 gtk/gtktextview.c:583 msgid "" "Whether to wrap lines never, at word boundaries, or at character boundaries" msgstr "" -#: gtk/gtktexttag.c:485 gtk/gtktextview.c:629 +#: gtk/gtktexttag.c:485 gtk/gtktextview.c:630 msgid "Tabs" msgstr "" -#: gtk/gtktexttag.c:486 gtk/gtktextview.c:630 +#: gtk/gtktexttag.c:486 gtk/gtktextview.c:631 msgid "Custom tabs for this text" msgstr "" @@ -5822,63 +5943,63 @@ msgstr "" msgid "Whether this tag affects the paragraph background color" msgstr "" -#: gtk/gtktextview.c:543 +#: gtk/gtktextview.c:544 msgid "Pixels Above Lines" msgstr "" -#: gtk/gtktextview.c:553 +#: gtk/gtktextview.c:554 msgid "Pixels Below Lines" msgstr "" -#: gtk/gtktextview.c:563 +#: gtk/gtktextview.c:564 msgid "Pixels Inside Wrap" msgstr "" -#: gtk/gtktextview.c:581 +#: gtk/gtktextview.c:582 msgid "Wrap Mode" msgstr "" -#: gtk/gtktextview.c:599 +#: gtk/gtktextview.c:600 msgid "Left Margin" msgstr "" -#: gtk/gtktextview.c:609 +#: gtk/gtktextview.c:610 msgid "Right Margin" msgstr "" -#: gtk/gtktextview.c:637 +#: gtk/gtktextview.c:638 msgid "Cursor Visible" msgstr "" -#: gtk/gtktextview.c:638 +#: gtk/gtktextview.c:639 msgid "If the insertion cursor is shown" msgstr "" -#: gtk/gtktextview.c:645 +#: gtk/gtktextview.c:646 msgid "Buffer" msgstr "" -#: gtk/gtktextview.c:646 +#: gtk/gtktextview.c:647 msgid "The buffer which is displayed" msgstr "" -#: gtk/gtktextview.c:654 +#: gtk/gtktextview.c:655 msgid "Whether entered text overwrites existing contents" msgstr "" -#: gtk/gtktextview.c:661 +#: gtk/gtktextview.c:662 msgid "Accepts tab" msgstr "" -#: gtk/gtktextview.c:662 +#: gtk/gtktextview.c:663 msgid "Whether Tab will result in a tab character being entered" msgstr "" -#: gtk/gtktextview.c:691 +#: gtk/gtktextview.c:692 msgid "Error underline color" msgstr "" -#: gtk/gtktextview.c:692 +#: gtk/gtktextview.c:693 msgid "Color with which to draw error-indication underlines" msgstr "" @@ -6058,345 +6179,353 @@ msgstr "" msgid "Spacing in pixels between the icon and label" msgstr "" -#: gtk/gtktoolitem.c:191 +#: gtk/gtktoolitem.c:207 msgid "" "Whether the toolbar item is considered important. When TRUE, toolbar buttons " "show text in GTK_TOOLBAR_BOTH_HORIZ mode" msgstr "" -#: gtk/gtktreemodelsort.c:274 +#: gtk/gtktreemodelsort.c:278 msgid "TreeModelSort Model" msgstr "" -#: gtk/gtktreemodelsort.c:275 +#: gtk/gtktreemodelsort.c:279 msgid "The model for the TreeModelSort to sort" msgstr "" -#: gtk/gtktreeview.c:570 +#: gtk/gtktreeview.c:561 msgid "TreeView Model" msgstr "" -#: gtk/gtktreeview.c:571 +#: gtk/gtktreeview.c:562 msgid "The model for the tree view" msgstr "" -#: gtk/gtktreeview.c:579 +#: gtk/gtktreeview.c:570 msgid "Horizontal Adjustment for the widget" msgstr "" -#: gtk/gtktreeview.c:587 +#: gtk/gtktreeview.c:578 msgid "Vertical Adjustment for the widget" msgstr "" -#: gtk/gtktreeview.c:594 +#: gtk/gtktreeview.c:585 msgid "Headers Visible" msgstr "" -#: gtk/gtktreeview.c:595 +#: gtk/gtktreeview.c:586 msgid "Show the column header buttons" msgstr "" -#: gtk/gtktreeview.c:602 +#: gtk/gtktreeview.c:593 msgid "Headers Clickable" msgstr "" -#: gtk/gtktreeview.c:603 +#: gtk/gtktreeview.c:594 msgid "Column headers respond to click events" msgstr "" -#: gtk/gtktreeview.c:610 +#: gtk/gtktreeview.c:601 msgid "Expander Column" msgstr "" -#: gtk/gtktreeview.c:611 +#: gtk/gtktreeview.c:602 msgid "Set the column for the expander column" msgstr "" -#: gtk/gtktreeview.c:626 +#: gtk/gtktreeview.c:617 msgid "Rules Hint" msgstr "" -#: gtk/gtktreeview.c:627 +#: gtk/gtktreeview.c:618 msgid "Set a hint to the theme engine to draw rows in alternating colors" msgstr "" -#: gtk/gtktreeview.c:634 +#: gtk/gtktreeview.c:625 msgid "Enable Search" msgstr "" -#: gtk/gtktreeview.c:635 +#: gtk/gtktreeview.c:626 msgid "View allows user to search through columns interactively" msgstr "" -#: gtk/gtktreeview.c:642 +#: gtk/gtktreeview.c:633 msgid "Search Column" msgstr "" -#: gtk/gtktreeview.c:643 +#: gtk/gtktreeview.c:634 msgid "Model column to search through during interactive search" msgstr "" -#: gtk/gtktreeview.c:663 +#: gtk/gtktreeview.c:654 msgid "Fixed Height Mode" msgstr "" -#: gtk/gtktreeview.c:664 +#: gtk/gtktreeview.c:655 msgid "Speeds up GtkTreeView by assuming that all rows have the same height" msgstr "" -#: gtk/gtktreeview.c:684 +#: gtk/gtktreeview.c:675 msgid "Hover Selection" msgstr "" -#: gtk/gtktreeview.c:685 +#: gtk/gtktreeview.c:676 msgid "Whether the selection should follow the pointer" msgstr "" -#: gtk/gtktreeview.c:704 +#: gtk/gtktreeview.c:695 #, fuzzy msgid "Hover Expand" msgstr "Þæt xpad" -#: gtk/gtktreeview.c:705 +#: gtk/gtktreeview.c:696 msgid "" "Whether rows should be expanded/collapsed when the pointer moves over them" msgstr "" -#: gtk/gtktreeview.c:719 +#: gtk/gtktreeview.c:710 msgid "Show Expanders" msgstr "" -#: gtk/gtktreeview.c:720 +#: gtk/gtktreeview.c:711 msgid "View has expanders" msgstr "" -#: gtk/gtktreeview.c:734 +#: gtk/gtktreeview.c:725 msgid "Level Indentation" msgstr "" -#: gtk/gtktreeview.c:735 +#: gtk/gtktreeview.c:726 msgid "Extra indentation for each level" msgstr "" -#: gtk/gtktreeview.c:744 +#: gtk/gtktreeview.c:735 msgid "Rubber Banding" msgstr "" -#: gtk/gtktreeview.c:745 +#: gtk/gtktreeview.c:736 msgid "" "Whether to enable selection of multiple items by dragging the mouse pointer" msgstr "" -#: gtk/gtktreeview.c:752 +#: gtk/gtktreeview.c:743 msgid "Enable Grid Lines" msgstr "" -#: gtk/gtktreeview.c:753 +#: gtk/gtktreeview.c:744 msgid "Whether grid lines should be drawn in the tree view" msgstr "" -#: gtk/gtktreeview.c:761 +#: gtk/gtktreeview.c:752 msgid "Enable Tree Lines" msgstr "" -#: gtk/gtktreeview.c:762 +#: gtk/gtktreeview.c:753 msgid "Whether tree lines should be drawn in the tree view" msgstr "" -#: gtk/gtktreeview.c:770 +#: gtk/gtktreeview.c:761 msgid "The column in the model containing the tooltip texts for the rows" msgstr "" -#: gtk/gtktreeview.c:792 +#: gtk/gtktreeview.c:783 msgid "Vertical Separator Width" msgstr "" -#: gtk/gtktreeview.c:793 +#: gtk/gtktreeview.c:784 msgid "Vertical space between cells. Must be an even number" msgstr "" -#: gtk/gtktreeview.c:801 +#: gtk/gtktreeview.c:792 msgid "Horizontal Separator Width" msgstr "" -#: gtk/gtktreeview.c:802 +#: gtk/gtktreeview.c:793 msgid "Horizontal space between cells. Must be an even number" msgstr "" -#: gtk/gtktreeview.c:810 +#: gtk/gtktreeview.c:801 msgid "Allow Rules" msgstr "" -#: gtk/gtktreeview.c:811 +#: gtk/gtktreeview.c:802 msgid "Allow drawing of alternating color rows" msgstr "" -#: gtk/gtktreeview.c:817 +#: gtk/gtktreeview.c:808 msgid "Indent Expanders" msgstr "" -#: gtk/gtktreeview.c:818 +#: gtk/gtktreeview.c:809 msgid "Make the expanders indented" msgstr "" -#: gtk/gtktreeview.c:824 +#: gtk/gtktreeview.c:815 msgid "Even Row Color" msgstr "" -#: gtk/gtktreeview.c:825 +#: gtk/gtktreeview.c:816 msgid "Color to use for even rows" msgstr "" -#: gtk/gtktreeview.c:831 +#: gtk/gtktreeview.c:822 msgid "Odd Row Color" msgstr "" -#: gtk/gtktreeview.c:832 +#: gtk/gtktreeview.c:823 msgid "Color to use for odd rows" msgstr "" -#: gtk/gtktreeview.c:838 +#: gtk/gtktreeview.c:829 msgid "Row Ending details" msgstr "" -#: gtk/gtktreeview.c:839 +#: gtk/gtktreeview.c:830 msgid "Enable extended row background theming" msgstr "" -#: gtk/gtktreeview.c:845 +#: gtk/gtktreeview.c:836 #, fuzzy msgid "Grid line width" msgstr "Séo fæste wídu" -#: gtk/gtktreeview.c:846 +#: gtk/gtktreeview.c:837 msgid "Width, in pixels, of the tree view grid lines" msgstr "" -#: gtk/gtktreeview.c:852 +#: gtk/gtktreeview.c:843 #, fuzzy msgid "Tree line width" msgstr "Séo fæste wídu" -#: gtk/gtktreeview.c:853 +#: gtk/gtktreeview.c:844 msgid "Width, in pixels, of the tree view lines" msgstr "" -#: gtk/gtktreeview.c:859 +#: gtk/gtktreeview.c:850 msgid "Grid line pattern" msgstr "" -#: gtk/gtktreeview.c:860 +#: gtk/gtktreeview.c:851 msgid "Dash pattern used to draw the tree view grid lines" msgstr "" -#: gtk/gtktreeview.c:866 +#: gtk/gtktreeview.c:857 msgid "Tree line pattern" msgstr "" -#: gtk/gtktreeview.c:867 +#: gtk/gtktreeview.c:858 msgid "Dash pattern used to draw the tree view lines" msgstr "" -#: gtk/gtktreeviewcolumn.c:192 +#: gtk/gtktreeviewcolumn.c:193 msgid "Whether to display the column" msgstr "" -#: gtk/gtktreeviewcolumn.c:199 gtk/gtkwindow.c:537 +#: gtk/gtktreeviewcolumn.c:200 gtk/gtkwindow.c:537 msgid "Resizable" msgstr "" -#: gtk/gtktreeviewcolumn.c:200 +#: gtk/gtktreeviewcolumn.c:201 msgid "Column is user-resizable" msgstr "" -#: gtk/gtktreeviewcolumn.c:208 +#: gtk/gtktreeviewcolumn.c:209 msgid "Current width of the column" msgstr "" -#: gtk/gtktreeviewcolumn.c:217 +#: gtk/gtktreeviewcolumn.c:218 msgid "Space which is inserted between cells" msgstr "" -#: gtk/gtktreeviewcolumn.c:225 +#: gtk/gtktreeviewcolumn.c:226 msgid "Sizing" msgstr "" -#: gtk/gtktreeviewcolumn.c:226 +#: gtk/gtktreeviewcolumn.c:227 msgid "Resize mode of the column" msgstr "" -#: gtk/gtktreeviewcolumn.c:234 +#: gtk/gtktreeviewcolumn.c:235 msgid "Fixed Width" msgstr "Fæst wídu" -#: gtk/gtktreeviewcolumn.c:235 +#: gtk/gtktreeviewcolumn.c:236 msgid "Current fixed width of the column" msgstr "" -#: gtk/gtktreeviewcolumn.c:244 +#: gtk/gtktreeviewcolumn.c:245 msgid "Minimum Width" msgstr "" -#: gtk/gtktreeviewcolumn.c:245 +#: gtk/gtktreeviewcolumn.c:246 msgid "Minimum allowed width of the column" msgstr "" -#: gtk/gtktreeviewcolumn.c:254 +#: gtk/gtktreeviewcolumn.c:255 msgid "Maximum Width" msgstr "" -#: gtk/gtktreeviewcolumn.c:255 +#: gtk/gtktreeviewcolumn.c:256 msgid "Maximum allowed width of the column" msgstr "" -#: gtk/gtktreeviewcolumn.c:265 +#: gtk/gtktreeviewcolumn.c:266 msgid "Title to appear in column header" msgstr "" -#: gtk/gtktreeviewcolumn.c:273 +#: gtk/gtktreeviewcolumn.c:274 msgid "Column gets share of extra width allocated to the widget" msgstr "" -#: gtk/gtktreeviewcolumn.c:280 +#: gtk/gtktreeviewcolumn.c:281 msgid "Clickable" msgstr "" -#: gtk/gtktreeviewcolumn.c:281 +#: gtk/gtktreeviewcolumn.c:282 msgid "Whether the header can be clicked" msgstr "" -#: gtk/gtktreeviewcolumn.c:289 +#: gtk/gtktreeviewcolumn.c:290 msgid "Widget" msgstr "" -#: gtk/gtktreeviewcolumn.c:290 +#: gtk/gtktreeviewcolumn.c:291 msgid "Widget to put in column header button instead of column title" msgstr "" -#: gtk/gtktreeviewcolumn.c:298 +#: gtk/gtktreeviewcolumn.c:299 msgid "X Alignment of the column header text or widget" msgstr "" -#: gtk/gtktreeviewcolumn.c:308 +#: gtk/gtktreeviewcolumn.c:309 msgid "Whether the column can be reordered around the headers" msgstr "" -#: gtk/gtktreeviewcolumn.c:315 +#: gtk/gtktreeviewcolumn.c:316 msgid "Sort indicator" msgstr "" -#: gtk/gtktreeviewcolumn.c:316 +#: gtk/gtktreeviewcolumn.c:317 msgid "Whether to show a sort indicator" msgstr "" -#: gtk/gtktreeviewcolumn.c:323 +#: gtk/gtktreeviewcolumn.c:324 msgid "Sort order" msgstr "" -#: gtk/gtktreeviewcolumn.c:324 +#: gtk/gtktreeviewcolumn.c:325 msgid "Sort direction the sort indicator should indicate" msgstr "" +#: gtk/gtktreeviewcolumn.c:341 +msgid "Sort column ID" +msgstr "" + +#: gtk/gtktreeviewcolumn.c:342 +msgid "Logical sort column ID this column sorts on when selected for sorting" +msgstr "" + #: gtk/gtkuimanager.c:223 msgid "Whether tearoff menu items should be added to menus" msgstr "" @@ -6425,282 +6554,290 @@ msgstr "" msgid "Determines how the shadowed box around the viewport is drawn" msgstr "" -#: gtk/gtkwidget.c:483 +#: gtk/gtkwidget.c:485 msgid "Widget name" msgstr "Wicgetnama" -#: gtk/gtkwidget.c:484 +#: gtk/gtkwidget.c:486 msgid "The name of the widget" msgstr "" -#: gtk/gtkwidget.c:490 +#: gtk/gtkwidget.c:492 msgid "Parent widget" msgstr "" -#: gtk/gtkwidget.c:491 +#: gtk/gtkwidget.c:493 msgid "The parent widget of this widget. Must be a Container widget" msgstr "" -#: gtk/gtkwidget.c:498 +#: gtk/gtkwidget.c:500 msgid "Width request" msgstr "" -#: gtk/gtkwidget.c:499 +#: gtk/gtkwidget.c:501 msgid "" "Override for width request of the widget, or -1 if natural request should be " "used" msgstr "" -#: gtk/gtkwidget.c:507 +#: gtk/gtkwidget.c:509 msgid "Height request" msgstr "" -#: gtk/gtkwidget.c:508 +#: gtk/gtkwidget.c:510 msgid "" "Override for height request of the widget, or -1 if natural request should " "be used" msgstr "" -#: gtk/gtkwidget.c:517 +#: gtk/gtkwidget.c:519 msgid "Whether the widget is visible" msgstr "" -#: gtk/gtkwidget.c:524 +#: gtk/gtkwidget.c:526 msgid "Whether the widget responds to input" msgstr "" -#: gtk/gtkwidget.c:530 +#: gtk/gtkwidget.c:532 msgid "Application paintable" msgstr "" -#: gtk/gtkwidget.c:531 +#: gtk/gtkwidget.c:533 msgid "Whether the application will paint directly on the widget" msgstr "" -#: gtk/gtkwidget.c:537 +#: gtk/gtkwidget.c:539 msgid "Can focus" msgstr "" -#: gtk/gtkwidget.c:538 +#: gtk/gtkwidget.c:540 msgid "Whether the widget can accept the input focus" msgstr "" -#: gtk/gtkwidget.c:544 +#: gtk/gtkwidget.c:546 msgid "Has focus" msgstr "" -#: gtk/gtkwidget.c:545 +#: gtk/gtkwidget.c:547 msgid "Whether the widget has the input focus" msgstr "" -#: gtk/gtkwidget.c:551 +#: gtk/gtkwidget.c:553 msgid "Is focus" msgstr "" -#: gtk/gtkwidget.c:552 +#: gtk/gtkwidget.c:554 msgid "Whether the widget is the focus widget within the toplevel" msgstr "" -#: gtk/gtkwidget.c:558 +#: gtk/gtkwidget.c:560 msgid "Can default" msgstr "" -#: gtk/gtkwidget.c:559 +#: gtk/gtkwidget.c:561 msgid "Whether the widget can be the default widget" msgstr "" -#: gtk/gtkwidget.c:565 +#: gtk/gtkwidget.c:567 msgid "Has default" msgstr "" -#: gtk/gtkwidget.c:566 +#: gtk/gtkwidget.c:568 msgid "Whether the widget is the default widget" msgstr "" -#: gtk/gtkwidget.c:572 +#: gtk/gtkwidget.c:574 msgid "Receives default" msgstr "" -#: gtk/gtkwidget.c:573 +#: gtk/gtkwidget.c:575 msgid "If TRUE, the widget will receive the default action when it is focused" msgstr "" -#: gtk/gtkwidget.c:579 +#: gtk/gtkwidget.c:581 msgid "Composite child" msgstr "" -#: gtk/gtkwidget.c:580 +#: gtk/gtkwidget.c:582 msgid "Whether the widget is part of a composite widget" msgstr "" -#: gtk/gtkwidget.c:586 +#: gtk/gtkwidget.c:588 msgid "Style" msgstr "" -#: gtk/gtkwidget.c:587 +#: gtk/gtkwidget.c:589 msgid "" "The style of the widget, which contains information about how it will look " "(colors etc)" msgstr "" -#: gtk/gtkwidget.c:593 +#: gtk/gtkwidget.c:595 msgid "Events" msgstr "" -#: gtk/gtkwidget.c:594 +#: gtk/gtkwidget.c:596 msgid "The event mask that decides what kind of GdkEvents this widget gets" msgstr "" -#: gtk/gtkwidget.c:601 +#: gtk/gtkwidget.c:603 msgid "Extension events" msgstr "" -#: gtk/gtkwidget.c:602 +#: gtk/gtkwidget.c:604 msgid "The mask that decides what kind of extension events this widget gets" msgstr "" -#: gtk/gtkwidget.c:609 +#: gtk/gtkwidget.c:611 msgid "No show all" msgstr "" -#: gtk/gtkwidget.c:610 +#: gtk/gtkwidget.c:612 msgid "Whether gtk_widget_show_all() should not affect this widget" msgstr "" -#: gtk/gtkwidget.c:633 +#: gtk/gtkwidget.c:635 msgid "Whether this widget has a tooltip" msgstr "" -#: gtk/gtkwidget.c:689 +#: gtk/gtkwidget.c:691 #, fuzzy msgid "Window" msgstr "Éagþyrelcynn" -#: gtk/gtkwidget.c:690 +#: gtk/gtkwidget.c:692 msgid "The widget's window if it is realized" msgstr "" -#: gtk/gtkwidget.c:2212 +#: gtk/gtkwidget.c:706 +msgid "Double Buffered" +msgstr "" + +#: gtk/gtkwidget.c:707 +msgid "Whether or not the widget is double buffered" +msgstr "" + +#: gtk/gtkwidget.c:2229 msgid "Interior Focus" msgstr "" -#: gtk/gtkwidget.c:2213 +#: gtk/gtkwidget.c:2230 msgid "Whether to draw the focus indicator inside widgets" msgstr "" -#: gtk/gtkwidget.c:2219 +#: gtk/gtkwidget.c:2236 msgid "Focus linewidth" msgstr "" -#: gtk/gtkwidget.c:2220 +#: gtk/gtkwidget.c:2237 msgid "Width, in pixels, of the focus indicator line" msgstr "" -#: gtk/gtkwidget.c:2226 +#: gtk/gtkwidget.c:2243 msgid "Focus line dash pattern" msgstr "" -#: gtk/gtkwidget.c:2227 +#: gtk/gtkwidget.c:2244 msgid "Dash pattern used to draw the focus indicator" msgstr "" -#: gtk/gtkwidget.c:2232 +#: gtk/gtkwidget.c:2249 msgid "Focus padding" msgstr "" -#: gtk/gtkwidget.c:2233 +#: gtk/gtkwidget.c:2250 msgid "Width, in pixels, between focus indicator and the widget 'box'" msgstr "" -#: gtk/gtkwidget.c:2238 +#: gtk/gtkwidget.c:2255 msgid "Cursor color" msgstr "" -#: gtk/gtkwidget.c:2239 +#: gtk/gtkwidget.c:2256 msgid "Color with which to draw insertion cursor" msgstr "" -#: gtk/gtkwidget.c:2244 +#: gtk/gtkwidget.c:2261 msgid "Secondary cursor color" msgstr "" -#: gtk/gtkwidget.c:2245 +#: gtk/gtkwidget.c:2262 msgid "" "Color with which to draw the secondary insertion cursor when editing mixed " "right-to-left and left-to-right text" msgstr "" -#: gtk/gtkwidget.c:2250 +#: gtk/gtkwidget.c:2267 msgid "Cursor line aspect ratio" msgstr "" -#: gtk/gtkwidget.c:2251 +#: gtk/gtkwidget.c:2268 msgid "Aspect ratio with which to draw insertion cursor" msgstr "" -#: gtk/gtkwidget.c:2265 +#: gtk/gtkwidget.c:2282 msgid "Draw Border" msgstr "" -#: gtk/gtkwidget.c:2266 +#: gtk/gtkwidget.c:2283 msgid "Size of areas outside the widget's allocation to draw" msgstr "" -#: gtk/gtkwidget.c:2279 +#: gtk/gtkwidget.c:2296 msgid "Unvisited Link Color" msgstr "" -#: gtk/gtkwidget.c:2280 +#: gtk/gtkwidget.c:2297 msgid "Color of unvisited links" msgstr "" -#: gtk/gtkwidget.c:2293 +#: gtk/gtkwidget.c:2310 msgid "Visited Link Color" msgstr "" -#: gtk/gtkwidget.c:2294 +#: gtk/gtkwidget.c:2311 msgid "Color of visited links" msgstr "" -#: gtk/gtkwidget.c:2308 +#: gtk/gtkwidget.c:2325 msgid "Wide Separators" msgstr "" -#: gtk/gtkwidget.c:2309 +#: gtk/gtkwidget.c:2326 msgid "" "Whether separators have configurable width and should be drawn using a box " "instead of a line" msgstr "" -#: gtk/gtkwidget.c:2323 +#: gtk/gtkwidget.c:2340 msgid "Separator Width" msgstr "" -#: gtk/gtkwidget.c:2324 +#: gtk/gtkwidget.c:2341 msgid "The width of separators if wide-separators is TRUE" msgstr "" -#: gtk/gtkwidget.c:2338 +#: gtk/gtkwidget.c:2355 msgid "Separator Height" msgstr "" -#: gtk/gtkwidget.c:2339 +#: gtk/gtkwidget.c:2356 msgid "The height of separators if \"wide-separators\" is TRUE" msgstr "" -#: gtk/gtkwidget.c:2353 +#: gtk/gtkwidget.c:2370 msgid "Horizontal Scroll Arrow Length" msgstr "" -#: gtk/gtkwidget.c:2354 +#: gtk/gtkwidget.c:2371 msgid "The length of horizontal scroll arrows" msgstr "" -#: gtk/gtkwidget.c:2368 +#: gtk/gtkwidget.c:2385 msgid "Vertical Scroll Arrow Length" msgstr "" -#: gtk/gtkwidget.c:2369 +#: gtk/gtkwidget.c:2386 msgid "The length of vertical scroll arrows" msgstr "" diff --git a/po-properties/ar.po b/po-properties/ar.po index 9c5021f92e..3297c86273 100644 --- a/po-properties/ar.po +++ b/po-properties/ar.po @@ -12,7 +12,7 @@ msgid "" msgstr "" "Project-Id-Version: gtk+-properties.HEAD.ar\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-06-15 20:53-0400\n" +"POT-Creation-Date: 2009-09-30 17:31-0400\n" "PO-Revision-Date: 2008-09-18 02:19+0300\n" "Last-Translator: Anas Afif Emad \n" "Language-Team: Arabic \n" @@ -23,6 +23,16 @@ msgstr "" "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " "&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" +#: gdk-pixbuf/gdk-pixbuf-simple-anim.c:165 +#, fuzzy +msgid "Loop" +msgstr "الشعار" + +#: gdk-pixbuf/gdk-pixbuf-simple-anim.c:166 +#, fuzzy +msgid "Whether the animation should loop when it reaches the end" +msgstr "فيما اذا كان المنتقى يتبع المؤشر" + #: gdk-pixbuf/gdk-pixbuf.c:89 msgid "Number of Channels" msgstr "عدد القنوات" @@ -55,7 +65,7 @@ msgstr "بيتات لكل نموذج" msgid "The number of bits per sample" msgstr "عدد البيتات لكل نموذج" -#: gdk-pixbuf/gdk-pixbuf.c:132 gtk/gtklayout.c:632 gtk/gtktreeviewcolumn.c:207 +#: gdk-pixbuf/gdk-pixbuf.c:132 gtk/gtklayout.c:632 gtk/gtktreeviewcolumn.c:208 msgid "Width" msgstr "العرض" @@ -96,12 +106,12 @@ msgstr "الشاشة الافتراضية" msgid "The default display for GDK" msgstr "شاشة GDK الافتراضية" -#: gdk/gdkpango.c:537 gtk/gtkinvisible.c:86 gtk/gtkmountoperation.c:155 -#: gtk/gtkstatusicon.c:277 gtk/gtkwindow.c:614 +#: gdk/gdkpango.c:538 gtk/gtkinvisible.c:86 gtk/gtkmountoperation.c:176 +#: gtk/gtkstatusicon.c:280 gtk/gtkwindow.c:614 msgid "Screen" msgstr "شاشة" -#: gdk/gdkpango.c:538 +#: gdk/gdkpango.c:539 msgid "the GdkScreen for the renderer" msgstr "الـ GdkScreen للرّاسم" @@ -121,6 +131,11 @@ msgstr "ميز الخط" msgid "The resolution for fonts on the screen" msgstr "ميز الخطوط على الشاشة" +#: gdk/gdkwindow.c:472 gdk/gdkwindow.c:473 +#, fuzzy +msgid "Cursor" +msgstr "وميض المؤشر" + #: gtk/gtkaboutdialog.c:239 msgid "Program name" msgstr "اسم البرنامج" @@ -260,7 +275,7 @@ msgid "A unique name for the action." msgstr "اسم متفرّد للعملية." #: gtk/gtkaction.c:198 gtk/gtkbutton.c:219 gtk/gtkexpander.c:195 -#: gtk/gtkframe.c:105 gtk/gtklabel.c:495 gtk/gtkmenuitem.c:300 +#: gtk/gtkframe.c:105 gtk/gtklabel.c:496 gtk/gtkmenuitem.c:305 #: gtk/gtktoolbutton.c:202 msgid "Label" msgstr "عنوان" @@ -293,30 +308,30 @@ msgstr "أيقونة من المخزون" msgid "The stock icon displayed in widgets representing this action." msgstr "أيقونة المخزون المعروضة في ودجات تمثل هذه العملية." -#: gtk/gtkaction.c:261 gtk/gtkstatusicon.c:250 +#: gtk/gtkaction.c:261 gtk/gtkstatusicon.c:253 msgid "GIcon" msgstr "أيقونة ج" #: gtk/gtkaction.c:262 gtk/gtkcellrendererpixbuf.c:206 gtk/gtkimage.c:248 -#: gtk/gtkstatusicon.c:251 +#: gtk/gtkstatusicon.c:254 msgid "The GIcon being displayed" msgstr "تم عرض GIcon" #: gtk/gtkaction.c:282 gtk/gtkcellrendererpixbuf.c:171 gtk/gtkimage.c:230 -#: gtk/gtkprinter.c:172 gtk/gtkstatusicon.c:234 gtk/gtkwindow.c:606 +#: gtk/gtkprinter.c:172 gtk/gtkstatusicon.c:237 gtk/gtkwindow.c:606 msgid "Icon Name" msgstr "اسم الأيقونة" #: gtk/gtkaction.c:283 gtk/gtkcellrendererpixbuf.c:172 gtk/gtkimage.c:231 -#: gtk/gtkstatusicon.c:235 +#: gtk/gtkstatusicon.c:238 msgid "The name of the icon from the icon theme" msgstr "اسم الايقونه من ايقونات النسق" -#: gtk/gtkaction.c:290 gtk/gtktoolitem.c:176 +#: gtk/gtkaction.c:290 gtk/gtktoolitem.c:192 msgid "Visible when horizontal" msgstr "مرئي عندما يكون افقي" -#: gtk/gtkaction.c:291 gtk/gtktoolitem.c:177 +#: gtk/gtkaction.c:291 gtk/gtktoolitem.c:193 msgid "" "Whether the toolbar item is visible when the toolbar is in a horizontal " "orientation." @@ -335,11 +350,11 @@ msgstr "" "عندما يكون TRUE، قوائم أدوات الوكيل لهذه العملية توضع في قائمة الأدوات " "الفائضة." -#: gtk/gtkaction.c:314 gtk/gtktoolitem.c:183 +#: gtk/gtkaction.c:314 gtk/gtktoolitem.c:199 msgid "Visible when vertical" msgstr "مرئي عندما يكون عمودي" -#: gtk/gtkaction.c:315 gtk/gtktoolitem.c:184 +#: gtk/gtkaction.c:315 gtk/gtktoolitem.c:200 msgid "" "Whether the toolbar item is visible when the toolbar is in a vertical " "orientation." @@ -347,7 +362,7 @@ msgstr "" "فيما إذا سيكون عنصر عمود الأدوات مرئيا عندما يكون عمود الأدوات في اتجاه " "عمودي." -#: gtk/gtkaction.c:322 gtk/gtktoolitem.c:190 +#: gtk/gtkaction.c:322 gtk/gtktoolitem.c:206 msgid "Is important" msgstr "مهم" @@ -368,7 +383,7 @@ msgid "When TRUE, empty menu proxies for this action are hidden." msgstr "عندما يكون TRUE، تخفى قوائم البروكسي الفارغة لهذه العملية." #: gtk/gtkaction.c:338 gtk/gtkactiongroup.c:177 gtk/gtkcellrenderer.c:193 -#: gtk/gtkwidget.c:523 +#: gtk/gtkwidget.c:525 msgid "Sensitive" msgstr "حساس" @@ -376,8 +391,8 @@ msgstr "حساس" msgid "Whether the action is enabled." msgstr "فيما إذا كانت العملية مفعلة." -#: gtk/gtkaction.c:345 gtk/gtkactiongroup.c:184 gtk/gtkstatusicon.c:293 -#: gtk/gtktreeviewcolumn.c:191 gtk/gtkwidget.c:516 +#: gtk/gtkaction.c:345 gtk/gtkactiongroup.c:184 gtk/gtkstatusicon.c:296 +#: gtk/gtktreeviewcolumn.c:192 gtk/gtkwidget.c:518 msgid "Visible" msgstr "مرئي" @@ -407,6 +422,24 @@ msgstr "فيما إذا كانت مجموعة العمليات مفعلة." msgid "Whether the action group is visible." msgstr "فيما إذا كانت مجموعة العمليات مرئية." +#: gtk/gtkactivatable.c:304 +#, fuzzy +msgid "Related Action" +msgstr "عملية" + +#: gtk/gtkactivatable.c:305 +msgid "The action this activatable will activate and receive updates from" +msgstr "" + +#: gtk/gtkactivatable.c:327 +msgid "Use Action Appearance" +msgstr "" + +#: gtk/gtkactivatable.c:328 +#, fuzzy +msgid "Whether to use the related actions appearance properties" +msgstr "فيما اذا كان من الممكن انتقاء نص الشارة بالفأرة" + #: gtk/gtkadjustment.c:93 gtk/gtkcellrendererprogress.c:128 #: gtk/gtkscalebutton.c:206 gtk/gtkspinbutton.c:269 msgid "Value" @@ -552,7 +585,7 @@ msgstr "ظل السهم" msgid "Appearance of the shadow surrounding the arrow" msgstr "مظهر الظل المحيط بالسهم" -#: gtk/gtkarrow.c:92 gtk/gtkmenu.c:689 gtk/gtkmenuitem.c:363 +#: gtk/gtkarrow.c:92 gtk/gtkmenu.c:711 gtk/gtkmenuitem.c:368 msgid "Arrow Scaling" msgstr "مباعدة الأسهم" @@ -648,43 +681,43 @@ msgstr "صفحة كاملة" msgid "Whether all required fields on the page have been filled out" msgstr "إذا تم ملأ كل المجالات المطلوبة على الصفحة" -#: gtk/gtkbbox.c:99 +#: gtk/gtkbbox.c:101 msgid "Minimum child width" msgstr "عرض الابن الادنى" -#: gtk/gtkbbox.c:100 +#: gtk/gtkbbox.c:102 msgid "Minimum width of buttons inside the box" msgstr "عرض الأزرار الأدنى داخل الصندوق" -#: gtk/gtkbbox.c:108 +#: gtk/gtkbbox.c:110 msgid "Minimum child height" msgstr "ارتفاع الابن الادنى" -#: gtk/gtkbbox.c:109 +#: gtk/gtkbbox.c:111 msgid "Minimum height of buttons inside the box" msgstr "ارتفاع الأزرار الأدنى داخل الصندوق" -#: gtk/gtkbbox.c:117 +#: gtk/gtkbbox.c:119 msgid "Child internal width padding" msgstr "حشو العرض الداخلي للابن" -#: gtk/gtkbbox.c:118 +#: gtk/gtkbbox.c:120 msgid "Amount to increase child's size on either side" msgstr "مقدار زيادة حجم الابن في كلا الجانبين" -#: gtk/gtkbbox.c:126 +#: gtk/gtkbbox.c:128 msgid "Child internal height padding" msgstr "حشو الارتفاع الداخلي للابن" -#: gtk/gtkbbox.c:127 +#: gtk/gtkbbox.c:129 msgid "Amount to increase child's size on the top and bottom" msgstr "مقدار زيادة حجم الابن في الأعلى والأسفل" -#: gtk/gtkbbox.c:135 +#: gtk/gtkbbox.c:137 msgid "Layout style" msgstr "نمط التخطيط" -#: gtk/gtkbbox.c:136 +#: gtk/gtkbbox.c:138 msgid "" "How to layout the buttons in the box. Possible values are default, spread, " "edge, start and end" @@ -692,11 +725,11 @@ msgstr "" "كيفية تخطيط الأزرار في الصندوق. القيم الممكنة هي افتراضا، انتشرا، حافة، بدء " "و، نهاية" -#: gtk/gtkbbox.c:144 +#: gtk/gtkbbox.c:146 msgid "Secondary" msgstr "ثانوي" -#: gtk/gtkbbox.c:145 +#: gtk/gtkbbox.c:147 msgid "" "If TRUE, the child appears in a secondary group of children, suitable for, e." "g., help buttons" @@ -704,8 +737,8 @@ msgstr "" "إذا كان TRUE، فسيبدو الابن في مجموعة ثانوية للأبناء، مناسبة لأزرار المساعدة " "مثلا." -#: gtk/gtkbox.c:130 gtk/gtkexpander.c:219 gtk/gtkiconview.c:664 -#: gtk/gtktreeviewcolumn.c:216 +#: gtk/gtkbox.c:130 gtk/gtkexpander.c:219 gtk/gtkiconview.c:665 +#: gtk/gtktreeviewcolumn.c:217 msgid "Spacing" msgstr "فراغات" @@ -723,7 +756,7 @@ msgid "Whether the children should all be the same size" msgstr "ما إذا سيكون كل الأبناء بنفس الحجم" #: gtk/gtkbox.c:148 gtk/gtkpreview.c:101 gtk/gtktoolbar.c:565 -#: gtk/gtktreeviewcolumn.c:272 +#: gtk/gtktreeviewcolumn.c:273 msgid "Expand" msgstr "تمديد" @@ -782,13 +815,13 @@ msgid "" "widget" msgstr "نص ودجة الشارة داخل الزر، إذا كان الزر يحوي كائن شارة" -#: gtk/gtkbutton.c:227 gtk/gtkexpander.c:203 gtk/gtklabel.c:516 -#: gtk/gtkmenuitem.c:315 gtk/gtktoolbutton.c:209 +#: gtk/gtkbutton.c:227 gtk/gtkexpander.c:203 gtk/gtklabel.c:517 +#: gtk/gtkmenuitem.c:320 gtk/gtktoolbutton.c:209 msgid "Use underline" msgstr "استخدام التسطير" -#: gtk/gtkbutton.c:228 gtk/gtkexpander.c:204 gtk/gtklabel.c:517 -#: gtk/gtkmenuitem.c:316 +#: gtk/gtkbutton.c:228 gtk/gtkexpander.c:204 gtk/gtklabel.c:518 +#: gtk/gtkmenuitem.c:321 msgid "" "If set, an underline in the text indicates the next character should be used " "for the mnemonic accelerator key" @@ -805,7 +838,7 @@ msgid "" "If set, the label is used to pick a stock item instead of being displayed" msgstr "إذا ضبط، فستستخدم العلامة لاختيار عنصر مخزن بدل عرضها" -#: gtk/gtkbutton.c:243 gtk/gtkcombobox.c:789 gtk/gtkfilechooserbutton.c:393 +#: gtk/gtkbutton.c:243 gtk/gtkcombobox.c:791 gtk/gtkfilechooserbutton.c:393 msgid "Focus on click" msgstr "تركيز عند النقر" @@ -891,7 +924,7 @@ msgid "" "rectangle" msgstr "إذا كانت خصائص child_displacement_x/_y تؤثر أيضا عل مستطيل التركيز" -#: gtk/gtkbutton.c:485 gtk/gtkentry.c:658 gtk/gtkentry.c:1682 +#: gtk/gtkbutton.c:485 gtk/gtkentry.c:689 gtk/gtkentry.c:1713 msgid "Inner Border" msgstr "الحد الداخلي" @@ -1113,35 +1146,35 @@ msgstr "ضبط خلفية الخلية" msgid "Whether this tag affects the cell background color" msgstr "فيما إذا كانت هذه الشارة تؤثر في لون خلفية الخلية" -#: gtk/gtkcellrendereraccel.c:113 +#: gtk/gtkcellrendereraccel.c:114 msgid "Accelerator key" msgstr "مفتاح التسريع" -#: gtk/gtkcellrendereraccel.c:114 +#: gtk/gtkcellrendereraccel.c:115 msgid "The keyval of the accelerator" msgstr "زر المسرّع" -#: gtk/gtkcellrendereraccel.c:130 +#: gtk/gtkcellrendereraccel.c:131 msgid "Accelerator modifiers" msgstr "مغيرات المُسرّع" -#: gtk/gtkcellrendereraccel.c:131 +#: gtk/gtkcellrendereraccel.c:132 msgid "The modifier mask of the accelerator" msgstr "قناع التغير للمسرّع" -#: gtk/gtkcellrendereraccel.c:148 +#: gtk/gtkcellrendereraccel.c:149 msgid "Accelerator keycode" msgstr "رمز مفتاح المُسرّع" -#: gtk/gtkcellrendereraccel.c:149 +#: gtk/gtkcellrendereraccel.c:150 msgid "The hardware keycode of the accelerator" msgstr "شفرة المسرّع" -#: gtk/gtkcellrendereraccel.c:168 +#: gtk/gtkcellrendereraccel.c:169 msgid "Accelerator Mode" msgstr "نمط المُسرّع" -#: gtk/gtkcellrendereraccel.c:169 +#: gtk/gtkcellrendereraccel.c:170 msgid "The type of accelerators" msgstr "نوع المسرّعات" @@ -1193,7 +1226,7 @@ msgstr "موسع·مغلق·للبيكسبف" msgid "Pixbuf for closed expander" msgstr "بيكسبف الموسع المغلق." -#: gtk/gtkcellrendererpixbuf.c:135 gtk/gtkimage.c:172 gtk/gtkstatusicon.c:226 +#: gtk/gtkcellrendererpixbuf.c:135 gtk/gtkimage.c:172 gtk/gtkstatusicon.c:229 msgid "Stock ID" msgstr "هوية المخزون" @@ -1202,7 +1235,7 @@ msgid "The stock ID of the stock icon to render" msgstr "هوية المخزون لأيقونة المخزون التي ستترجم" #: gtk/gtkcellrendererpixbuf.c:143 gtk/gtkrecentmanager.c:245 -#: gtk/gtkstatusicon.c:267 +#: gtk/gtkstatusicon.c:270 msgid "Size" msgstr "الحجم" @@ -1235,8 +1268,8 @@ msgid "Value of the progress bar" msgstr "قيمة شريط التَّقدم" #: gtk/gtkcellrendererprogress.c:146 gtk/gtkcellrenderertext.c:195 -#: gtk/gtkentry.c:701 gtk/gtkmessagedialog.c:153 gtk/gtkprogressbar.c:184 -#: gtk/gtktextbuffer.c:198 +#: gtk/gtkentry.c:732 gtk/gtkentrybuffer.c:353 gtk/gtkmessagedialog.c:153 +#: gtk/gtkprogressbar.c:184 gtk/gtktextbuffer.c:198 msgid "Text" msgstr "النص" @@ -1273,7 +1306,7 @@ msgid "The vertical text alignment, from 0 (top) to 1 (bottom)." msgstr "التنسيق العمودي، من 0 (فوق) إلى 1 (تحت)" #: gtk/gtkcellrendererprogress.c:221 gtk/gtkiconview.c:729 -#: gtk/gtkorientable.c:74 gtk/gtkprogressbar.c:126 gtk/gtkstatusicon.c:325 +#: gtk/gtkorientable.c:74 gtk/gtkprogressbar.c:126 gtk/gtkstatusicon.c:328 #: gtk/gtktrayicon-x11.c:110 msgid "Orientation" msgstr "الاتجاه" @@ -1319,7 +1352,7 @@ msgstr "تعليم" msgid "Marked up text to render" msgstr "نص معلّم للترجمة" -#: gtk/gtkcellrenderertext.c:211 gtk/gtklabel.c:502 +#: gtk/gtkcellrenderertext.c:211 gtk/gtklabel.c:503 msgid "Attributes" msgstr "الصفات" @@ -1367,12 +1400,12 @@ msgstr "لون الواجهة الأمامية" msgid "Foreground color as a GdkColor" msgstr "لون الواجهة الأمامية كـ GdkColor" -#: gtk/gtkcellrenderertext.c:261 gtk/gtkentry.c:625 gtk/gtktexttag.c:251 -#: gtk/gtktextview.c:573 +#: gtk/gtkcellrenderertext.c:261 gtk/gtkentry.c:656 gtk/gtktexttag.c:251 +#: gtk/gtktextview.c:574 msgid "Editable" msgstr "قابل للتحرير" -#: gtk/gtkcellrenderertext.c:262 gtk/gtktexttag.c:252 gtk/gtktextview.c:574 +#: gtk/gtkcellrenderertext.c:262 gtk/gtktexttag.c:252 gtk/gtktextview.c:575 msgid "Whether the text can be modified by the user" msgstr "فيما إذا يمكن تعديل النص عن طريق المستخدم" @@ -1477,7 +1510,7 @@ msgstr "" "اللغة التي فيها هذا النص، كشفرة ISO. يمكن لبانكو إستعمال هذا كتلميحة عند رسم " "النص. إذا كنت لا تفهم هذا المتغيّر فأنك ربما لا تستحقّه" -#: gtk/gtkcellrenderertext.c:411 gtk/gtklabel.c:627 gtk/gtkprogressbar.c:206 +#: gtk/gtkcellrenderertext.c:411 gtk/gtklabel.c:628 gtk/gtkprogressbar.c:206 msgid "Ellipsize" msgstr "قص" @@ -1488,11 +1521,11 @@ msgid "" msgstr "المكان المفضل لقطع النص." #: gtk/gtkcellrenderertext.c:431 gtk/gtkfilechooserbutton.c:421 -#: gtk/gtklabel.c:647 +#: gtk/gtklabel.c:648 msgid "Width In Characters" msgstr "العرض بالحروف" -#: gtk/gtkcellrenderertext.c:432 gtk/gtklabel.c:648 +#: gtk/gtkcellrenderertext.c:432 gtk/gtklabel.c:649 msgid "The desired width of the label, in characters" msgstr "العرض المطلوب للعنوان بالمحارف" @@ -1507,7 +1540,7 @@ msgid "" msgstr "" "كيفية كسر النص الى سطور متعددة، إذا كان لا يوجد هناك فراغ كافٍ لكامل النص." -#: gtk/gtkcellrenderertext.c:470 gtk/gtkcombobox.c:678 +#: gtk/gtkcellrenderertext.c:470 gtk/gtkcombobox.c:680 msgid "Wrap width" msgstr "عرض اللف" @@ -1515,7 +1548,7 @@ msgstr "عرض اللف" msgid "The width at which the text is wrapped" msgstr "عرض لف النص" -#: gtk/gtkcellrenderertext.c:491 gtk/gtktreeviewcolumn.c:297 +#: gtk/gtkcellrenderertext.c:491 gtk/gtktreeviewcolumn.c:298 msgid "Alignment" msgstr "تنسيق" @@ -1712,7 +1745,7 @@ msgstr "فراغات المؤشر" msgid "Spacing around check or radio indicator" msgstr "الفراغات حول مؤشر الفحص أو الإشعاع" -#: gtk/gtkcheckmenuitem.c:98 gtk/gtkmenu.c:500 gtk/gtktoggleaction.c:119 +#: gtk/gtkcheckmenuitem.c:98 gtk/gtkmenu.c:501 gtk/gtktoggleaction.c:119 #: gtk/gtktogglebutton.c:115 gtk/gtktoggletoolbutton.c:114 msgid "Active" msgstr "نشط" @@ -1746,7 +1779,8 @@ msgid "Whether or not to give the color an alpha value" msgstr "فيما إذا سيمنح للون شفافية أم لا" #: gtk/gtkcolorbutton.c:186 gtk/gtkfilechooserbutton.c:407 -#: gtk/gtkfontbutton.c:142 gtk/gtkprintjob.c:116 gtk/gtktreeviewcolumn.c:264 +#: gtk/gtkfontbutton.c:142 gtk/gtkprintjob.c:116 gtk/gtkstatusicon.c:424 +#: gtk/gtktreeviewcolumn.c:265 msgid "Title" msgstr "العنوان" @@ -1874,113 +1908,113 @@ msgstr "القيمة في القائمة" msgid "Whether entered values must already be present in the list" msgstr "فيما إذا وجب على القيم المدخلة أن تكون موجودةً في القائمة" -#: gtk/gtkcombobox.c:661 +#: gtk/gtkcombobox.c:663 msgid "ComboBox model" msgstr "نموذج ComboBox" -#: gtk/gtkcombobox.c:662 +#: gtk/gtkcombobox.c:664 msgid "The model for the combo box" msgstr "نموذج لصندوق المجموعات" -#: gtk/gtkcombobox.c:679 +#: gtk/gtkcombobox.c:681 msgid "Wrap width for laying out the items in a grid" msgstr "عرض اللف عند تصميم العناصر في الشبكة" -#: gtk/gtkcombobox.c:701 +#: gtk/gtkcombobox.c:703 msgid "Row span column" msgstr "عمود إمتداد السطر" -#: gtk/gtkcombobox.c:702 +#: gtk/gtkcombobox.c:704 msgid "TreeModel column containing the row span values" msgstr "عمود نموذج الشجرة المحتوي على قيم إمتداد السطر" -#: gtk/gtkcombobox.c:723 +#: gtk/gtkcombobox.c:725 msgid "Column span column" msgstr "عمود إمتداد العمود" -#: gtk/gtkcombobox.c:724 +#: gtk/gtkcombobox.c:726 msgid "TreeModel column containing the column span values" msgstr "عمود TreeModel الحاوي لقيم مدى العمود" -#: gtk/gtkcombobox.c:745 +#: gtk/gtkcombobox.c:747 msgid "Active item" msgstr "العنصر النشط" -#: gtk/gtkcombobox.c:746 +#: gtk/gtkcombobox.c:748 msgid "The item which is currently active" msgstr "العنصر النشط حاليا" -#: gtk/gtkcombobox.c:765 gtk/gtkuimanager.c:222 +#: gtk/gtkcombobox.c:767 gtk/gtkuimanager.c:222 msgid "Add tearoffs to menus" msgstr "إضافة قاطفات للقوائم" -#: gtk/gtkcombobox.c:766 +#: gtk/gtkcombobox.c:768 msgid "Whether dropdowns should have a tearoff menu item" msgstr "فيما إذا وجب أن يكون للقوائم النازلة عنصر قطع" -#: gtk/gtkcombobox.c:781 gtk/gtkentry.c:650 +#: gtk/gtkcombobox.c:783 gtk/gtkentry.c:681 msgid "Has Frame" msgstr "له إطار" -#: gtk/gtkcombobox.c:782 +#: gtk/gtkcombobox.c:784 msgid "Whether the combo box draws a frame around the child" msgstr "إذا ما كان صندوق الإختيار يرسم إطارا حول الإبن" -#: gtk/gtkcombobox.c:790 +#: gtk/gtkcombobox.c:792 msgid "Whether the combo box grabs focus when it is clicked with the mouse" msgstr "فيما إذا سيأخذ الزر التركيز عند نقره بالفأرة" -#: gtk/gtkcombobox.c:805 gtk/gtkmenu.c:555 +#: gtk/gtkcombobox.c:807 gtk/gtkmenu.c:556 msgid "Tearoff Title" msgstr "قطف العنوان" -#: gtk/gtkcombobox.c:806 +#: gtk/gtkcombobox.c:808 msgid "" "A title that may be displayed by the window manager when the popup is torn-" "off" msgstr "عنوان قد يعرض من قبل مدير النوافذ عند إلغاء القوائم المنبثقة" -#: gtk/gtkcombobox.c:823 +#: gtk/gtkcombobox.c:825 msgid "Popup shown" msgstr "نافذة قافزة معروضة" -#: gtk/gtkcombobox.c:824 +#: gtk/gtkcombobox.c:826 msgid "Whether the combo's dropdown is shown" msgstr "فيما إذا يتم عرض قائمة الصندوق" -#: gtk/gtkcombobox.c:840 +#: gtk/gtkcombobox.c:842 msgid "Button Sensitivity" msgstr "حساسية الزر" -#: gtk/gtkcombobox.c:841 +#: gtk/gtkcombobox.c:843 msgid "Whether the dropdown button is sensitive when the model is empty" msgstr "فيما إذا كان زر القائمة المنسدلة حساساً عندما يكون النموذج فارغاً" -#: gtk/gtkcombobox.c:848 +#: gtk/gtkcombobox.c:850 msgid "Appears as list" msgstr "يظهر كقائمة" -#: gtk/gtkcombobox.c:849 +#: gtk/gtkcombobox.c:851 msgid "Whether dropdowns should look like lists rather than menus" msgstr "" "فما إذا القوائم النازلة لصناديق المجموعات يجب أن تكون قوائم بسيطة عوض قوائم " "حاسوب" -#: gtk/gtkcombobox.c:865 +#: gtk/gtkcombobox.c:867 msgid "Arrow Size" msgstr "حجم السهم" -#: gtk/gtkcombobox.c:866 +#: gtk/gtkcombobox.c:868 msgid "The minimum size of the arrow in the combo box" msgstr "الحجم الأدنى للسهم في صندوق الإختيار" -#: gtk/gtkcombobox.c:881 gtk/gtkentry.c:750 gtk/gtkhandlebox.c:174 +#: gtk/gtkcombobox.c:883 gtk/gtkentry.c:781 gtk/gtkhandlebox.c:174 #: gtk/gtkmenubar.c:194 gtk/gtkstatusbar.c:186 gtk/gtktoolbar.c:623 #: gtk/gtkviewport.c:122 msgid "Shadow type" msgstr "نوع الظل" -#: gtk/gtkcombobox.c:882 +#: gtk/gtkcombobox.c:884 msgid "Which kind of shadow to draw around the combo box" msgstr "نوع الظل حول صندوق الإختيار" @@ -2056,7 +2090,7 @@ msgstr "له فاصل" msgid "The dialog has a separator bar above its buttons" msgstr "للحوار عمود فاصل فوق أزراره" -#: gtk/gtkdialog.c:191 +#: gtk/gtkdialog.c:191 gtk/gtkinfobar.c:439 msgid "Content area border" msgstr "حد منطقة المحتوى" @@ -2064,7 +2098,7 @@ msgstr "حد منطقة المحتوى" msgid "Width of border around the main dialog area" msgstr "عرض حد منطقة الحوار الرئيسية" -#: gtk/gtkdialog.c:209 +#: gtk/gtkdialog.c:209 gtk/gtkinfobar.c:456 #, fuzzy msgid "Content area spacing" msgstr "حشو المحتوى" @@ -2074,15 +2108,15 @@ msgstr "حشو المحتوى" msgid "Spacing between elements of the main dialog area" msgstr "الفراغ بين نص القيمة ومنطقة المتزحلق/المنخفض" -#: gtk/gtkdialog.c:217 +#: gtk/gtkdialog.c:217 gtk/gtkinfobar.c:472 msgid "Button spacing" msgstr "فراغات الأزار" -#: gtk/gtkdialog.c:218 +#: gtk/gtkdialog.c:218 gtk/gtkinfobar.c:473 msgid "Spacing between buttons" msgstr "الفراغات بين الأزرار" -#: gtk/gtkdialog.c:226 +#: gtk/gtkdialog.c:226 gtk/gtkinfobar.c:488 msgid "Action area border" msgstr "حد منطقة العمل" @@ -2090,67 +2124,76 @@ msgstr "حد منطقة العمل" msgid "Width of border around the button area at the bottom of the dialog" msgstr "عرض حد منطقة الزر أسفل الصندوق" -#: gtk/gtkentry.c:605 gtk/gtklabel.c:590 +#: gtk/gtkentry.c:628 +#, fuzzy +msgid "Text Buffer" +msgstr "ذاكرة وسيطة" + +#: gtk/gtkentry.c:629 +msgid "Text buffer object which actually stores entry text" +msgstr "" + +#: gtk/gtkentry.c:636 gtk/gtklabel.c:591 msgid "Cursor Position" msgstr "موقع المؤشر" -#: gtk/gtkentry.c:606 gtk/gtklabel.c:591 +#: gtk/gtkentry.c:637 gtk/gtklabel.c:592 msgid "The current position of the insertion cursor in chars" msgstr "الموقع الحالي لمؤشر الإدخال في الرموز" -#: gtk/gtkentry.c:615 gtk/gtklabel.c:600 +#: gtk/gtkentry.c:646 gtk/gtklabel.c:601 msgid "Selection Bound" msgstr "قيد المنتقى" -#: gtk/gtkentry.c:616 gtk/gtklabel.c:601 +#: gtk/gtkentry.c:647 gtk/gtklabel.c:602 msgid "" "The position of the opposite end of the selection from the cursor in chars" msgstr "موقع النهاية المعكوسة للمنتقى من المؤشر في الرموز" -#: gtk/gtkentry.c:626 +#: gtk/gtkentry.c:657 msgid "Whether the entry contents can be edited" msgstr "فيما إذا كانت محتويات الخانة قابلة للتحرير" -#: gtk/gtkentry.c:633 +#: gtk/gtkentry.c:664 gtk/gtkentrybuffer.c:383 msgid "Maximum length" msgstr "الارتفاع الأقصى" -#: gtk/gtkentry.c:634 +#: gtk/gtkentry.c:665 gtk/gtkentrybuffer.c:384 msgid "Maximum number of characters for this entry. Zero if no maximum" msgstr "العدد الأقصى للرموز لهذا المدخل. صفر إذا لم يكن أقصى" -#: gtk/gtkentry.c:642 +#: gtk/gtkentry.c:673 msgid "Visibility" msgstr "الرؤية" -#: gtk/gtkentry.c:643 +#: gtk/gtkentry.c:674 msgid "" "FALSE displays the \"invisible char\" instead of the actual text (password " "mode)" msgstr "FALSE سيعرض \"الرمز المخفي\" بدلًا من النص الحالي (نمط كلمة السر)" -#: gtk/gtkentry.c:651 +#: gtk/gtkentry.c:682 msgid "FALSE removes outside bevel from entry" msgstr "FALSE يحذف الحافة الخارجية من الخانة" -#: gtk/gtkentry.c:659 +#: gtk/gtkentry.c:690 msgid "" "Border between text and frame. Overrides the inner-border style property" msgstr "الحد بين النص والاطار. تتجاوز خاصية أسلوب الحد-الداخلي" -#: gtk/gtkentry.c:666 gtk/gtkentry.c:1232 +#: gtk/gtkentry.c:697 gtk/gtkentry.c:1263 msgid "Invisible character" msgstr "رمز مخفي" -#: gtk/gtkentry.c:667 gtk/gtkentry.c:1233 +#: gtk/gtkentry.c:698 gtk/gtkentry.c:1264 msgid "The character to use when masking entry contents (in \"password mode\")" msgstr "الرمز الذي سيستخدم لاخفاء محتويات الخانة (في \"نمط كلمة السر\")" -#: gtk/gtkentry.c:674 +#: gtk/gtkentry.c:705 msgid "Activates default" msgstr "تنشيط الافتراضات" -#: gtk/gtkentry.c:675 +#: gtk/gtkentry.c:706 msgid "" "Whether to activate the default widget (such as the default button in a " "dialog) when Enter is pressed" @@ -2158,326 +2201,336 @@ msgstr "" "فيما اذا وجب تنشيط الودجة الافتراضية (مثل الزر الافتراضي في حوار ما)عند نقر " "زر الادخال" -#: gtk/gtkentry.c:681 +#: gtk/gtkentry.c:712 msgid "Width in chars" msgstr "العرض بالرموز" -#: gtk/gtkentry.c:682 +#: gtk/gtkentry.c:713 msgid "Number of characters to leave space for in the entry" msgstr "عدد الرموز التي ستترك لها فراغات في الخانة" -#: gtk/gtkentry.c:691 +#: gtk/gtkentry.c:722 msgid "Scroll offset" msgstr "تكافؤ اللف" -#: gtk/gtkentry.c:692 +#: gtk/gtkentry.c:723 msgid "Number of pixels of the entry scrolled off the screen to the left" msgstr "عدد بكسلات الخانة الملفوفة خارج الشاشة إلى اليسار" -#: gtk/gtkentry.c:702 +#: gtk/gtkentry.c:733 msgid "The contents of the entry" msgstr "محتويات الخانة" -#: gtk/gtkentry.c:717 gtk/gtkmisc.c:73 +#: gtk/gtkentry.c:748 gtk/gtkmisc.c:73 msgid "X align" msgstr "تنسيق س" -#: gtk/gtkentry.c:718 gtk/gtkmisc.c:74 +#: gtk/gtkentry.c:749 gtk/gtkmisc.c:74 msgid "" "The horizontal alignment, from 0 (left) to 1 (right). Reversed for RTL " "layouts." msgstr "الترصيف الأفقي، من 0 (يسار) إلى 1 (يمين). مقلوب لتصاميم RTL" -#: gtk/gtkentry.c:734 +#: gtk/gtkentry.c:765 msgid "Truncate multiline" msgstr "قطع السطور المتعددة" -#: gtk/gtkentry.c:735 +#: gtk/gtkentry.c:766 msgid "Whether to truncate multiline pastes to one line." msgstr "ما إذا سيتم قطع نص ملصوق متعدد السطور إلى سطر واحد" -#: gtk/gtkentry.c:751 +#: gtk/gtkentry.c:782 msgid "Which kind of shadow to draw around the entry when has-frame is set" msgstr "أي نوع من الظل المرسوم حول المدخل عند تحديد has-frame" -#: gtk/gtkentry.c:766 gtk/gtktextview.c:653 +#: gtk/gtkentry.c:797 gtk/gtktextview.c:654 msgid "Overwrite mode" msgstr "نسق التنميق" -#: gtk/gtkentry.c:767 +#: gtk/gtkentry.c:798 msgid "Whether new text overwrites existing text" msgstr "فيما إذا كان النص الجديد يكتب فوق النص الموجود" -#: gtk/gtkentry.c:781 +#: gtk/gtkentry.c:812 gtk/gtkentrybuffer.c:368 msgid "Text length" msgstr "طول النص" -#: gtk/gtkentry.c:782 +#: gtk/gtkentry.c:813 msgid "Length of the text currently in the entry" msgstr "طول النص الموجود حالياً في المُدخل" -#: gtk/gtkentry.c:797 +#: gtk/gtkentry.c:828 #, fuzzy msgid "Invisible char set" msgstr "تعيين غير المرئية" -#: gtk/gtkentry.c:798 +#: gtk/gtkentry.c:829 #, fuzzy msgid "Whether the invisible char has been set" msgstr "فيما إذا كتم تحديد icon-size" -#: gtk/gtkentry.c:816 +#: gtk/gtkentry.c:847 msgid "Caps Lock warning" msgstr "" -#: gtk/gtkentry.c:817 +#: gtk/gtkentry.c:848 msgid "Whether password entries will show a warning when Caps Lock is on" msgstr "" -#: gtk/gtkentry.c:831 +#: gtk/gtkentry.c:862 #, fuzzy msgid "Progress Fraction" msgstr "جزء" -#: gtk/gtkentry.c:832 +#: gtk/gtkentry.c:863 #, fuzzy msgid "The current fraction of the task that's been completed" msgstr "جزء من العمل الذي تم" -#: gtk/gtkentry.c:849 +#: gtk/gtkentry.c:880 #, fuzzy msgid "Progress Pulse Step" msgstr "خطوة النبض" -#: gtk/gtkentry.c:850 +#: gtk/gtkentry.c:881 #, fuzzy msgid "" "The fraction of total entry width to move the progress bouncing block for " "each call to gtk_entry_progress_pulse()" msgstr "جزء التقدم الكلي لتحريك الكتلة القافزة عند النبض" -#: gtk/gtkentry.c:866 +#: gtk/gtkentry.c:897 #, fuzzy msgid "Primary pixbuf" msgstr "بكسبف" -#: gtk/gtkentry.c:867 +#: gtk/gtkentry.c:898 #, fuzzy msgid "Primary pixbuf for the entry" msgstr "بيكسبف للموسع المفتوح" -#: gtk/gtkentry.c:881 +#: gtk/gtkentry.c:912 #, fuzzy msgid "Secondary pixbuf" msgstr "النص الثانوي" -#: gtk/gtkentry.c:882 +#: gtk/gtkentry.c:913 #, fuzzy msgid "Secondary pixbuf for the entry" msgstr "متخطي التقدم الثانوي" -#: gtk/gtkentry.c:896 +#: gtk/gtkentry.c:927 msgid "Primary stock ID" msgstr "" -#: gtk/gtkentry.c:897 +#: gtk/gtkentry.c:928 msgid "Stock ID for primary icon" msgstr "" -#: gtk/gtkentry.c:911 +#: gtk/gtkentry.c:942 #, fuzzy msgid "Secondary stock ID" msgstr "النص الثانوي" -#: gtk/gtkentry.c:912 +#: gtk/gtkentry.c:943 msgid "Stock ID for secondary icon" msgstr "" -#: gtk/gtkentry.c:926 -#, fuzzy -msgid "Primary icon name" -msgstr "قائمة أسماء الإيقونات" - -#: gtk/gtkentry.c:927 -msgid "Icon name for primary icon" -msgstr "" - -#: gtk/gtkentry.c:941 -#, fuzzy -msgid "Secondary icon name" -msgstr "النص الثانوي" - -#: gtk/gtkentry.c:942 -msgid "Icon name for secondary icon" -msgstr "" - -#: gtk/gtkentry.c:956 -msgid "Primary GIcon" -msgstr "" - #: gtk/gtkentry.c:957 #, fuzzy +msgid "Primary icon name" +msgstr "قائمة أسماء الإيقونات" + +#: gtk/gtkentry.c:958 +msgid "Icon name for primary icon" +msgstr "" + +#: gtk/gtkentry.c:972 +#, fuzzy +msgid "Secondary icon name" +msgstr "النص الثانوي" + +#: gtk/gtkentry.c:973 +msgid "Icon name for secondary icon" +msgstr "" + +#: gtk/gtkentry.c:987 +msgid "Primary GIcon" +msgstr "" + +#: gtk/gtkentry.c:988 +#, fuzzy msgid "GIcon for primary icon" msgstr "أيقونة لهذه النافذة" -#: gtk/gtkentry.c:971 +#: gtk/gtkentry.c:1002 #, fuzzy msgid "Secondary GIcon" msgstr "ثانوي" -#: gtk/gtkentry.c:972 +#: gtk/gtkentry.c:1003 msgid "GIcon for secondary icon" msgstr "" -#: gtk/gtkentry.c:986 +#: gtk/gtkentry.c:1017 #, fuzzy msgid "Primary storage type" msgstr "نوع التخزين" -#: gtk/gtkentry.c:987 +#: gtk/gtkentry.c:1018 #, fuzzy msgid "The representation being used for primary icon" msgstr "التقديم المستعمل لبيانات الرسوم" -#: gtk/gtkentry.c:1002 +#: gtk/gtkentry.c:1033 #, fuzzy msgid "Secondary storage type" msgstr "متخطي التقدم الثانوي" -#: gtk/gtkentry.c:1003 +#: gtk/gtkentry.c:1034 #, fuzzy msgid "The representation being used for secondary icon" msgstr "التقديم المستعمل لبيانات الرسوم" -#: gtk/gtkentry.c:1024 +#: gtk/gtkentry.c:1055 msgid "Primary icon activatable" msgstr "" -#: gtk/gtkentry.c:1025 +#: gtk/gtkentry.c:1056 #, fuzzy msgid "Whether the primary icon is activatable" msgstr "فيما إذا كانت العملية مفعلة." -#: gtk/gtkentry.c:1045 +#: gtk/gtkentry.c:1076 #, fuzzy msgid "Secondary icon activatable" msgstr "مؤشر ا?دخال الثانوي" -#: gtk/gtkentry.c:1046 +#: gtk/gtkentry.c:1077 #, fuzzy msgid "Whether the secondary icon is activatable" msgstr "فيما إذا كانت العملية مفعلة." -#: gtk/gtkentry.c:1068 +#: gtk/gtkentry.c:1099 #, fuzzy msgid "Primary icon sensitive" msgstr "عرض حساسية الخلية" -#: gtk/gtkentry.c:1069 +#: gtk/gtkentry.c:1100 #, fuzzy msgid "Whether the primary icon is sensitive" msgstr "فيما إذا كان تطابق عناصر القائمة حساس للحالة" -#: gtk/gtkentry.c:1090 +#: gtk/gtkentry.c:1121 #, fuzzy msgid "Secondary icon sensitive" msgstr "النص الثانوي" -#: gtk/gtkentry.c:1091 +#: gtk/gtkentry.c:1122 #, fuzzy msgid "Whether the secondary icon is sensitive" msgstr "فيما إذا كانت العملية مفعلة." -#: gtk/gtkentry.c:1107 +#: gtk/gtkentry.c:1138 #, fuzzy msgid "Primary icon tooltip text" msgstr "عرض حساسية الخلية" -#: gtk/gtkentry.c:1108 gtk/gtkentry.c:1144 +#: gtk/gtkentry.c:1139 gtk/gtkentry.c:1175 #, fuzzy msgid "The contents of the tooltip on the primary icon" msgstr "نص تلميحة لهذه الودجة" -#: gtk/gtkentry.c:1124 +#: gtk/gtkentry.c:1155 #, fuzzy msgid "Secondary icon tooltip text" msgstr "مؤشر ا?دخال الثانوي" -#: gtk/gtkentry.c:1125 gtk/gtkentry.c:1163 +#: gtk/gtkentry.c:1156 gtk/gtkentry.c:1194 #, fuzzy msgid "The contents of the tooltip on the secondary icon" msgstr "نص تلميحة لهذه الودجة" -#: gtk/gtkentry.c:1143 +#: gtk/gtkentry.c:1174 #, fuzzy msgid "Primary icon tooltip markup" msgstr "قائمة أسماء الإيقونات" -#: gtk/gtkentry.c:1162 +#: gtk/gtkentry.c:1193 #, fuzzy msgid "Secondary icon tooltip markup" msgstr "النص الثانوي" -#: gtk/gtkentry.c:1182 gtk/gtktextview.c:681 +#: gtk/gtkentry.c:1213 gtk/gtktextview.c:682 #, fuzzy msgid "IM module" msgstr "وحدة IM الإفتراضية" -#: gtk/gtkentry.c:1183 gtk/gtktextview.c:682 +#: gtk/gtkentry.c:1214 gtk/gtktextview.c:683 #, fuzzy msgid "Which IM module should be used" msgstr "وحدة IM الإفتراضية" -#: gtk/gtkentry.c:1197 +#: gtk/gtkentry.c:1228 #, fuzzy msgid "Icon Prelight" msgstr "الارتفاع" -#: gtk/gtkentry.c:1198 +#: gtk/gtkentry.c:1229 #, fuzzy msgid "Whether activatable icons should prelight when hovered" msgstr "فيما إذا كان سيتم عرض الألسنة أم لا" -#: gtk/gtkentry.c:1211 +#: gtk/gtkentry.c:1242 #, fuzzy msgid "Progress Border" msgstr "حد منخفض" -#: gtk/gtkentry.c:1212 +#: gtk/gtkentry.c:1243 #, fuzzy msgid "Border around the progress bar" msgstr "النص على عمود التقدم" -#: gtk/gtkentry.c:1683 +#: gtk/gtkentry.c:1714 msgid "Border between text and frame." msgstr "الحد بين النص والاطار." -#: gtk/gtkentry.c:1697 +#: gtk/gtkentry.c:1728 #, fuzzy msgid "State Hint" msgstr "نص الحالة" -#: gtk/gtkentry.c:1698 +#: gtk/gtkentry.c:1729 #, fuzzy msgid "Whether to pass a proper state when drawing shadow or background" msgstr "صورة بيتماب المستخدمة كغلاف أثناء رسم الواجهة الخلفية للنص" -#: gtk/gtkentry.c:1703 gtk/gtklabel.c:830 +#: gtk/gtkentry.c:1734 gtk/gtklabel.c:848 msgid "Select on focus" msgstr "اختيار عند التركيز" -#: gtk/gtkentry.c:1704 +#: gtk/gtkentry.c:1735 msgid "Whether to select the contents of an entry when it is focused" msgstr "فيما اذا سيقع انتقاء محتويات خانة عند تركيزها" -#: gtk/gtkentry.c:1718 +#: gtk/gtkentry.c:1749 msgid "Password Hint Timeout" msgstr "مدة عرض تلميحة كلمة السر" -#: gtk/gtkentry.c:1719 +#: gtk/gtkentry.c:1750 msgid "How long to show the last input character in hidden entries" msgstr "مدة ظهور الحرف المدخل الأخير في المداخل المخفية" +#: gtk/gtkentrybuffer.c:354 +#, fuzzy +msgid "The contents of the buffer" +msgstr "محتويات الخانة" + +#: gtk/gtkentrybuffer.c:369 +#, fuzzy +msgid "Length of the text currently in the buffer" +msgstr "طول النص الموجود حالياً في المُدخل" + #: gtk/gtkentrycompletion.c:279 msgid "Completion Model" msgstr "نمط الانهاء" @@ -2494,7 +2547,7 @@ msgstr "الطول الأدنى للمفتاح" msgid "Minimum length of the search key in order to look up matches" msgstr "الطول الأدنى لمفتاح البحث حتى يمكن البحث عن المتطابقات" -#: gtk/gtkentrycompletion.c:303 gtk/gtkiconview.c:585 +#: gtk/gtkentrycompletion.c:303 gtk/gtkiconview.c:586 msgid "Text column" msgstr "عمود النص" @@ -2578,11 +2631,11 @@ msgstr "فيما إذا وقع فتح الموسع للكشف عن الودجة msgid "Text of the expander's label" msgstr "نص شارة الموسع" -#: gtk/gtkexpander.c:211 gtk/gtklabel.c:509 +#: gtk/gtkexpander.c:211 gtk/gtklabel.c:510 msgid "Use markup" msgstr "استخدام التعليم" -#: gtk/gtkexpander.c:212 gtk/gtklabel.c:510 +#: gtk/gtkexpander.c:212 gtk/gtklabel.c:511 msgid "The text of the label includes XML markup. See pango_parse_markup()" msgstr "نص الشارة يحوي تعليم XML. راجع pango_parse_markup()" @@ -2598,11 +2651,11 @@ msgstr "ودجة الشارة" msgid "A widget to display in place of the usual expander label" msgstr "الودجة التي ستعرض عوض شارة الموسع الاعتادية" -#: gtk/gtkexpander.c:236 gtk/gtktreeview.c:783 +#: gtk/gtkexpander.c:236 gtk/gtktreeview.c:774 msgid "Expander Size" msgstr "حجم الموسع" -#: gtk/gtkexpander.c:237 gtk/gtktreeview.c:784 +#: gtk/gtkexpander.c:237 gtk/gtktreeview.c:775 msgid "Size of the expander arrow" msgstr "حجم سهم الموسع" @@ -2703,6 +2756,20 @@ msgstr "" "اذا كان حوار اختيار الملف في حالة الحفظ سيعرض سؤال لتأكيد الكتابة الفوقية ان " "كان ذلك مطلوبا." +#: gtk/gtkfilechooser.c:283 +#, fuzzy +msgid "Allow folders creation" +msgstr "إظهار عمليات الملفات" + +#: gtk/gtkfilechooser.c:284 +#, fuzzy +msgid "" +"Whether a file chooser not in open mode will offer the user to create new " +"folders." +msgstr "" +"اذا كان حوار اختيار الملف في حالة الحفظ سيعرض سؤال لتأكيد الكتابة الفوقية ان " +"كان ذلك مطلوبا." + #: gtk/gtkfilechooserbutton.c:376 msgid "Dialog" msgstr "حوار" @@ -2720,7 +2787,7 @@ msgid "The desired width of the button widget, in characters." msgstr "العرض المطلوب لودجة الزر، بالمحارف" #: gtk/gtkfilesel.c:526 gtk/gtkimage.c:163 gtk/gtkrecentmanager.c:214 -#: gtk/gtkstatusicon.c:218 +#: gtk/gtkstatusicon.c:221 msgid "Filename" msgstr "اسم الملف" @@ -2894,83 +2961,83 @@ msgid "" "detached." msgstr "قيمة منطقية تحدد فيما إذا كان صندوق المداولة للابن متصل أو منفصل." -#: gtk/gtkiconview.c:548 +#: gtk/gtkiconview.c:549 msgid "Selection mode" msgstr "نمط الانتقاء" -#: gtk/gtkiconview.c:549 +#: gtk/gtkiconview.c:550 msgid "The selection mode" msgstr "نمط الانتقاء" -#: gtk/gtkiconview.c:567 +#: gtk/gtkiconview.c:568 msgid "Pixbuf column" msgstr "عمود Pixbuf" -#: gtk/gtkiconview.c:568 +#: gtk/gtkiconview.c:569 msgid "Model column used to retrieve the icon pixbuf from" msgstr "نموذج العمود المستخدم لاستعادة ايقونة pixbuf" -#: gtk/gtkiconview.c:586 +#: gtk/gtkiconview.c:587 msgid "Model column used to retrieve the text from" msgstr "نموذج العمود المستخدم لاستعادة النص" -#: gtk/gtkiconview.c:605 +#: gtk/gtkiconview.c:606 msgid "Markup column" msgstr "عمود الترميز" -#: gtk/gtkiconview.c:606 +#: gtk/gtkiconview.c:607 msgid "Model column used to retrieve the text if using Pango markup" msgstr "نموذج العمود المستخدم لاستعادة النص اذا تم استخدام ترميز بانغو" -#: gtk/gtkiconview.c:613 +#: gtk/gtkiconview.c:614 msgid "Icon View Model" msgstr "نمط عرض الأيقونات" -#: gtk/gtkiconview.c:614 +#: gtk/gtkiconview.c:615 msgid "The model for the icon view" msgstr "نمط عرض الأيقونات" -#: gtk/gtkiconview.c:630 +#: gtk/gtkiconview.c:631 msgid "Number of columns" msgstr "عدد الأعمدة" -#: gtk/gtkiconview.c:631 +#: gtk/gtkiconview.c:632 msgid "Number of columns to display" msgstr "عدد الأعمدة المعروضة" -#: gtk/gtkiconview.c:648 +#: gtk/gtkiconview.c:649 msgid "Width for each item" msgstr "عرض كل عنصر" -#: gtk/gtkiconview.c:649 +#: gtk/gtkiconview.c:650 msgid "The width used for each item" msgstr "عرض كل عنصر" -#: gtk/gtkiconview.c:665 +#: gtk/gtkiconview.c:666 msgid "Space which is inserted between cells of an item" msgstr "الفراغ بين خلايا العنصر" -#: gtk/gtkiconview.c:680 +#: gtk/gtkiconview.c:681 msgid "Row Spacing" msgstr "فراغات السطور" -#: gtk/gtkiconview.c:681 +#: gtk/gtkiconview.c:682 msgid "Space which is inserted between grid rows" msgstr "الفراغ المدرج بين صفوف الشبكة" -#: gtk/gtkiconview.c:696 +#: gtk/gtkiconview.c:697 msgid "Column Spacing" msgstr "فراغات العمود" -#: gtk/gtkiconview.c:697 +#: gtk/gtkiconview.c:698 msgid "Space which is inserted between grid columns" msgstr "الفراغ المدرج بين أعمدة الشبكة" -#: gtk/gtkiconview.c:712 +#: gtk/gtkiconview.c:713 msgid "Margin" msgstr "الحاشية" -#: gtk/gtkiconview.c:713 +#: gtk/gtkiconview.c:714 msgid "Space which is inserted at the edges of the icon view" msgstr "الفراغ الملحق عند حدود الأيقونات" @@ -2979,15 +3046,15 @@ msgid "" "How the text and icon of each item are positioned relative to each other" msgstr "كيفية وضع نص و أيقون كل عنصر بالنسبة لبعضهما" -#: gtk/gtkiconview.c:746 gtk/gtktreeview.c:618 gtk/gtktreeviewcolumn.c:307 +#: gtk/gtkiconview.c:746 gtk/gtktreeview.c:609 gtk/gtktreeviewcolumn.c:308 msgid "Reorderable" msgstr "قابل لإعادة الترتيب" -#: gtk/gtkiconview.c:747 gtk/gtktreeview.c:619 +#: gtk/gtkiconview.c:747 gtk/gtktreeview.c:610 msgid "View is reorderable" msgstr "العرض قابل لإعادة الترتيب" -#: gtk/gtkiconview.c:754 gtk/gtktreeview.c:769 +#: gtk/gtkiconview.c:754 gtk/gtktreeview.c:760 msgid "Tooltip Column" msgstr "عمود التلميحات" @@ -2995,27 +3062,36 @@ msgstr "عمود التلميحات" msgid "The column in the model containing the tooltip texts for the items" msgstr "عمود النموذج المحتوي على التلميحات للعناصر." -#: gtk/gtkiconview.c:766 +#: gtk/gtkiconview.c:772 +#, fuzzy +msgid "Item Padding" +msgstr "الحشو الأسفل" + +#: gtk/gtkiconview.c:773 +msgid "Padding around icon view items" +msgstr "" + +#: gtk/gtkiconview.c:782 msgid "Selection Box Color" msgstr "لون علبة الإختيار" -#: gtk/gtkiconview.c:767 +#: gtk/gtkiconview.c:783 msgid "Color of the selection box" msgstr "لون صندوق الإختيار" -#: gtk/gtkiconview.c:773 +#: gtk/gtkiconview.c:789 msgid "Selection Box Alpha" msgstr "ألفا علبة الإختيار" -#: gtk/gtkiconview.c:774 +#: gtk/gtkiconview.c:790 msgid "Opacity of the selection box" msgstr "شفافية علبة الإختيار" -#: gtk/gtkimage.c:131 gtk/gtkstatusicon.c:210 +#: gtk/gtkimage.c:131 gtk/gtkstatusicon.c:213 msgid "Pixbuf" msgstr "بكسبف" -#: gtk/gtkimage.c:132 gtk/gtkstatusicon.c:211 +#: gtk/gtkimage.c:132 gtk/gtkstatusicon.c:214 msgid "A GdkPixbuf to display" msgstr "GdkPixbuf لعرضه" @@ -3043,11 +3119,11 @@ msgstr "غلاف" msgid "Mask bitmap to use with GdkImage or GdkPixmap" msgstr "بيتماب الغلاف لاستخدامه مع GdkImage أو GdkPixmap" -#: gtk/gtkimage.c:164 gtk/gtkstatusicon.c:219 +#: gtk/gtkimage.c:164 gtk/gtkstatusicon.c:222 msgid "Filename to load and display" msgstr "اسم الملف للتحميل و العرض" -#: gtk/gtkimage.c:173 gtk/gtkstatusicon.c:227 +#: gtk/gtkimage.c:173 gtk/gtkstatusicon.c:230 msgid "Stock ID for a stock image to display" msgstr "هوية المخزون لصورة مخزون للعرض" @@ -3083,11 +3159,11 @@ msgstr "رسوم متحركة" msgid "GdkPixbufAnimation to display" msgstr "GdkPixbufAnimation لعرضها" -#: gtk/gtkimage.c:255 gtk/gtkstatusicon.c:258 +#: gtk/gtkimage.c:255 gtk/gtkstatusicon.c:261 msgid "Storage type" msgstr "نوع التخزين" -#: gtk/gtkimage.c:256 gtk/gtkstatusicon.c:259 +#: gtk/gtkimage.c:256 gtk/gtkstatusicon.c:262 msgid "The representation being used for image data" msgstr "التقديم المستعمل لبيانات الرسوم" @@ -3109,7 +3185,7 @@ msgstr "" msgid "Whether the image will always be shown" msgstr "ما إذا كان الكائن ظاهرا" -#: gtk/gtkimagemenuitem.c:184 gtk/gtkmenu.c:515 +#: gtk/gtkimagemenuitem.c:184 gtk/gtkmenu.c:516 msgid "Accel Group" msgstr "مجموعة Accel" @@ -3126,23 +3202,46 @@ msgstr "اظهار صور القوائم" msgid "Whether images should be shown in menus" msgstr "فيما إذا سيتم إظهار صور في القوائم" +#: gtk/gtkinfobar.c:384 gtk/gtkmessagedialog.c:128 +msgid "Message Type" +msgstr "نوع الرسالة" + +#: gtk/gtkinfobar.c:385 gtk/gtkmessagedialog.c:129 +msgid "The type of message" +msgstr "نوع الرسالة" + +#: gtk/gtkinfobar.c:440 +#, fuzzy +msgid "Width of border around the content area" +msgstr "عرض حد منطقة الحوار الرئيسية" + +#: gtk/gtkinfobar.c:457 +#, fuzzy +msgid "Spacing between elements of the area" +msgstr "الفراغ بين نص القيمة ومنطقة المتزحلق/المنخفض" + +#: gtk/gtkinfobar.c:489 +#, fuzzy +msgid "Width of border around the action area" +msgstr "عرض حد منطقة الحوار الرئيسية" + #: gtk/gtkinvisible.c:87 gtk/gtkwindow.c:615 msgid "The screen where this window will be displayed" msgstr "الشاشة التي ستعرض فيها هذه النافذة" -#: gtk/gtklabel.c:496 +#: gtk/gtklabel.c:497 msgid "The text of the label" msgstr "نص الشارة" -#: gtk/gtklabel.c:503 +#: gtk/gtklabel.c:504 msgid "A list of style attributes to apply to the text of the label" msgstr "قائمة لصفات الأساليب لتطبيقها على نص العلامة" -#: gtk/gtklabel.c:524 gtk/gtktexttag.c:359 gtk/gtktextview.c:590 +#: gtk/gtklabel.c:525 gtk/gtktexttag.c:359 gtk/gtktextview.c:591 msgid "Justification" msgstr "ضبط" -#: gtk/gtklabel.c:525 +#: gtk/gtklabel.c:526 msgid "" "The alignment of the lines in the text of the label relative to each other. " "This does NOT affect the alignment of the label within its allocation. See " @@ -3151,57 +3250,57 @@ msgstr "" "ترصيف السطور في نص العلامة بالنسبة لبعضها البعض. لا يؤثّر هذا في ترصيف " "العلامة نفسها في مكانها المخصص لها. راجع GtkMisc::xalign للمزيد من العملومات" -#: gtk/gtklabel.c:533 +#: gtk/gtklabel.c:534 msgid "Pattern" msgstr "نمط" -#: gtk/gtklabel.c:534 +#: gtk/gtklabel.c:535 msgid "" "A string with _ characters in positions correspond to characters in the text " "to underline" msgstr "سلسلة برموز _ في مواقع معينة يرمز لرموز ستسطّر في النص" -#: gtk/gtklabel.c:541 +#: gtk/gtklabel.c:542 msgid "Line wrap" msgstr "لف السطور" -#: gtk/gtklabel.c:542 +#: gtk/gtklabel.c:543 msgid "If set, wrap lines if the text becomes too wide" msgstr "اذا ضبط، فستلف السطور عندما يصبح النص واسعا جدا" -#: gtk/gtklabel.c:557 +#: gtk/gtklabel.c:558 msgid "Line wrap mode" msgstr "نسق نظام الالتواء" -#: gtk/gtklabel.c:558 +#: gtk/gtklabel.c:559 msgid "If wrap is set, controls how linewrapping is done" msgstr "اذا كان اللف مفعّلا، التحكم في كيفية لف السطر." -#: gtk/gtklabel.c:565 +#: gtk/gtklabel.c:566 msgid "Selectable" msgstr "قابل للاختيار" -#: gtk/gtklabel.c:566 +#: gtk/gtklabel.c:567 msgid "Whether the label text can be selected with the mouse" msgstr "فيما اذا كان من الممكن انتقاء نص الشارة بالفأرة" -#: gtk/gtklabel.c:572 +#: gtk/gtklabel.c:573 msgid "Mnemonic key" msgstr "مفتاح الإختصار المسطّر" -#: gtk/gtklabel.c:573 +#: gtk/gtklabel.c:574 msgid "The mnemonic accelerator key for this label" msgstr "مفتاح الإختصار المسطر لهذه العلامة" -#: gtk/gtklabel.c:581 +#: gtk/gtklabel.c:582 msgid "Mnemonic widget" msgstr "ودجة مفتاح الإختصار المسطر" -#: gtk/gtklabel.c:582 +#: gtk/gtklabel.c:583 msgid "The widget to be activated when the label's mnemonic key is pressed" msgstr "الودجة التي ستفعل عند نقر مفتاح الإختصار المسطر" -#: gtk/gtklabel.c:628 +#: gtk/gtklabel.c:629 msgid "" "The preferred place to ellipsize the string, if the label does not have " "enough room to display the entire string" @@ -3209,31 +3308,41 @@ msgstr "" "المكان المفضل لوضع القطع في النص، إذا كانت التسمية لا تملك المكان الكافي " "لعرض كل النص" -#: gtk/gtklabel.c:668 +#: gtk/gtklabel.c:669 msgid "Single Line Mode" msgstr "نمط سطر وحيد" -#: gtk/gtklabel.c:669 +#: gtk/gtklabel.c:670 msgid "Whether the label is in single line mode" msgstr "فيما إذا كانت العلامة في نمط السطر الوحيد" -#: gtk/gtklabel.c:686 +#: gtk/gtklabel.c:687 msgid "Angle" msgstr "الزاويه" -#: gtk/gtklabel.c:687 +#: gtk/gtklabel.c:688 msgid "Angle at which the label is rotated" msgstr "الزاوية التي سيدوّرها العنوان" -#: gtk/gtklabel.c:707 +#: gtk/gtklabel.c:708 msgid "Maximum Width In Characters" msgstr "العرض الأكبر بالحروف" -#: gtk/gtklabel.c:708 +#: gtk/gtklabel.c:709 msgid "The desired maximum width of the label, in characters" msgstr "العرض الأقصى المطلوب للتسمية، بالمحارف" -#: gtk/gtklabel.c:831 +#: gtk/gtklabel.c:727 +#, fuzzy +msgid "Track visited links" +msgstr "لون الوصلات المزارة" + +#: gtk/gtklabel.c:728 +#, fuzzy +msgid "Whether visited links should be tracked" +msgstr "فيما إذا يفترض اظهار العناصر الخاصة" + +#: gtk/gtklabel.c:849 msgid "Whether to select the contents of a selectable label when it is focused" msgstr "فيما اذا سيتم اختيار محتويات التسمية عند التركيز عليها" @@ -3277,168 +3386,179 @@ msgstr "تمت زيارته" msgid "Whether this link has been visited." msgstr "فيما إذا تمت زيارة هذا الرابط" -#: gtk/gtkmenu.c:501 +#: gtk/gtkmenu.c:502 msgid "The currently selected menu item" msgstr "اسم عنصر القائمة المحدد حالياً" -#: gtk/gtkmenu.c:516 +#: gtk/gtkmenu.c:517 msgid "The accel group holding accelerators for the menu" msgstr "المسرّع مجموعة accel للقائمة" -#: gtk/gtkmenu.c:530 gtk/gtkmenuitem.c:285 +#: gtk/gtkmenu.c:531 gtk/gtkmenuitem.c:290 msgid "Accel Path" msgstr "مسار Accel" -#: gtk/gtkmenu.c:531 +#: gtk/gtkmenu.c:532 msgid "An accel path used to conveniently construct accel paths of child items" msgstr "مسار الـ accel المستخدم لتسهيل بناء مسارات الـ accel للعناصر الأبناء" -#: gtk/gtkmenu.c:547 +#: gtk/gtkmenu.c:548 msgid "Attach Widget" msgstr "ربط ودجة" -#: gtk/gtkmenu.c:548 +#: gtk/gtkmenu.c:549 msgid "The widget the menu is attached to" msgstr "الودجة التي ترتبط بها القائمة" -#: gtk/gtkmenu.c:556 +#: gtk/gtkmenu.c:557 msgid "" "A title that may be displayed by the window manager when this menu is torn-" "off" msgstr "عنوان قد يعرض من قبل مدير النوافذ عند قطف هذه القائمة" -#: gtk/gtkmenu.c:570 +#: gtk/gtkmenu.c:571 msgid "Tearoff State" msgstr "حالة القطع" -#: gtk/gtkmenu.c:571 +#: gtk/gtkmenu.c:572 msgid "A boolean that indicates whether the menu is torn-off" msgstr "عدد منطقي يحدد ما إذا كانت القائمة مغلقة أم لا" -#: gtk/gtkmenu.c:585 +#: gtk/gtkmenu.c:586 msgid "Monitor" msgstr "الشاشة" -#: gtk/gtkmenu.c:586 +#: gtk/gtkmenu.c:587 msgid "The monitor the menu will be popped up on" msgstr "الشاشة التي ستنبثق عليها القائمة" -#: gtk/gtkmenu.c:592 +#: gtk/gtkmenu.c:593 msgid "Vertical Padding" msgstr "الحشو العمودي" -#: gtk/gtkmenu.c:593 +#: gtk/gtkmenu.c:594 msgid "Extra space at the top and bottom of the menu" msgstr "مساحة اضافية لأعلى وأسفل القائمة" -#: gtk/gtkmenu.c:601 +#: gtk/gtkmenu.c:616 +msgid "Reserve Toggle Size" +msgstr "" + +#: gtk/gtkmenu.c:617 +#, fuzzy +msgid "" +"A boolean that indicates whether the menu reserves space for toggles and " +"icons" +msgstr "عدد منطقي يحدد ما إذا كانت القائمة مغلقة أم لا" + +#: gtk/gtkmenu.c:623 msgid "Horizontal Padding" msgstr "الحشو الأفقي" -#: gtk/gtkmenu.c:602 +#: gtk/gtkmenu.c:624 msgid "Extra space at the left and right edges of the menu" msgstr "فراغ اضافي عند حواف القائمة يمينا ويسارا" -#: gtk/gtkmenu.c:610 +#: gtk/gtkmenu.c:632 msgid "Vertical Offset" msgstr "التكافؤ العمودي" -#: gtk/gtkmenu.c:611 +#: gtk/gtkmenu.c:633 msgid "" "When the menu is a submenu, position it this number of pixels offset " "vertically" msgstr "" "عندما تكون القائمة قائمة فرعيّة تموقع هذا العدد من البكسلات عموديّا كتعويض" -#: gtk/gtkmenu.c:619 +#: gtk/gtkmenu.c:641 msgid "Horizontal Offset" msgstr "التكافؤ العمودي" -#: gtk/gtkmenu.c:620 +#: gtk/gtkmenu.c:642 msgid "" "When the menu is a submenu, position it this number of pixels offset " "horizontally" msgstr "عندما·تكون·القائمة·قائمة·فرعيّة·تموقع·هذا·العدد·من·البكسلات·أفقيّا·كتعويض" -#: gtk/gtkmenu.c:628 +#: gtk/gtkmenu.c:650 msgid "Double Arrows" msgstr "أسهم مزدوجة" -#: gtk/gtkmenu.c:629 +#: gtk/gtkmenu.c:651 msgid "When scrolling, always show both arrows." msgstr "عند التحريك اظهر كل الأسهم" -#: gtk/gtkmenu.c:642 +#: gtk/gtkmenu.c:664 #, fuzzy msgid "Arrow Placement" msgstr "إزاحة السهم في س" -#: gtk/gtkmenu.c:643 +#: gtk/gtkmenu.c:665 msgid "Indicates where scroll arrows should be placed" msgstr "" -#: gtk/gtkmenu.c:651 +#: gtk/gtkmenu.c:673 msgid "Left Attach" msgstr "ربط على اليسار" -#: gtk/gtkmenu.c:652 gtk/gtktable.c:174 +#: gtk/gtkmenu.c:674 gtk/gtktable.c:174 msgid "The column number to attach the left side of the child to" msgstr "رقم العمود الذي إليه ستربط الجهة اليسرى للإبن" -#: gtk/gtkmenu.c:659 +#: gtk/gtkmenu.c:681 msgid "Right Attach" msgstr "ربط على اليمين" -#: gtk/gtkmenu.c:660 +#: gtk/gtkmenu.c:682 msgid "The column number to attach the right side of the child to" msgstr "رقم·العمود·الذي·إليه·ستربط·الجهة·اليمنى·للإبن" -#: gtk/gtkmenu.c:667 +#: gtk/gtkmenu.c:689 msgid "Top Attach" msgstr "ربط بالأعلى" -#: gtk/gtkmenu.c:668 +#: gtk/gtkmenu.c:690 msgid "The row number to attach the top of the child to" msgstr "رقم·السطر·الذي·إليه·ستربط·الجهة·العليا·للإبن" -#: gtk/gtkmenu.c:675 +#: gtk/gtkmenu.c:697 msgid "Bottom Attach" msgstr "ربط بالأسفل" -#: gtk/gtkmenu.c:676 gtk/gtktable.c:195 +#: gtk/gtkmenu.c:698 gtk/gtktable.c:195 msgid "The row number to attach the bottom of the child to" msgstr "رقم·السطر·الذي·إليه·ستربط·الجهة·السفلى·للإبن" -#: gtk/gtkmenu.c:690 +#: gtk/gtkmenu.c:712 msgid "Arbitrary constant to scale down the size of the scroll arrow" msgstr "" -#: gtk/gtkmenu.c:777 +#: gtk/gtkmenu.c:799 msgid "Can change accelerators" msgstr "من الممكن تغيير مفاتيح الاختصار" -#: gtk/gtkmenu.c:778 +#: gtk/gtkmenu.c:800 msgid "" "Whether menu accelerators can be changed by pressing a key over the menu item" msgstr "" "فيما اذا كان من الممكن تغيير مفاتيح اختصار القوائم بضغط مفتاح فوق عنصر " "القائمة" -#: gtk/gtkmenu.c:783 +#: gtk/gtkmenu.c:805 msgid "Delay before submenus appear" msgstr "التأخير قبل ظهور القوائم المحوية" -#: gtk/gtkmenu.c:784 +#: gtk/gtkmenu.c:806 msgid "" "Minimum time the pointer must stay over a menu item before the submenu appear" msgstr "" "الوقت الأدنى الذي يجب أن يبقى فيه المؤشر فوق عنصر قائمة لتظهر القائمة المحوية" -#: gtk/gtkmenu.c:791 +#: gtk/gtkmenu.c:813 msgid "Delay before hiding a submenu" msgstr "التأخير قبل اخفاء قائمة محوية" -#: gtk/gtkmenu.c:792 +#: gtk/gtkmenu.c:814 msgid "" "The time before hiding a submenu when the pointer is moving towards the " "submenu" @@ -3480,42 +3600,42 @@ msgstr "التأخير قبل ظهور القائم المنحدرة" msgid "Delay before the submenus of a menu bar appear" msgstr "التأخير قبل أن تظهر القوائم المحوية لعمود قائمة" -#: gtk/gtkmenuitem.c:252 +#: gtk/gtkmenuitem.c:257 msgid "Right Justified" msgstr "مُحاذَى لليمين" -#: gtk/gtkmenuitem.c:253 +#: gtk/gtkmenuitem.c:258 msgid "" "Sets whether the menu item appears justified at the right side of a menu bar" msgstr "" "يضبط فيما إذا كان عنصر القائمة سيظهر محاذياً للجزء الأيمن من شريط القائمة" -#: gtk/gtkmenuitem.c:267 +#: gtk/gtkmenuitem.c:272 msgid "Submenu" msgstr "قائمة سفلية" -#: gtk/gtkmenuitem.c:268 +#: gtk/gtkmenuitem.c:273 msgid "The submenu attached to the menu item, or NULL if it has none" msgstr "القائمة السفلية الملصقة بعنصر القائمة، أو NULL إذا لم يكن لها شيء" -#: gtk/gtkmenuitem.c:286 +#: gtk/gtkmenuitem.c:291 msgid "Sets the accelerator path of the menu item" msgstr "يضبط مسار معجّل عناصر القائمة" -#: gtk/gtkmenuitem.c:301 +#: gtk/gtkmenuitem.c:306 #, fuzzy msgid "The text for the child label" msgstr "نص الشارة" -#: gtk/gtkmenuitem.c:364 +#: gtk/gtkmenuitem.c:369 msgid "Amount of space used up by arrow, relative to the menu item's font size" msgstr "كمية الفضاء المستخدم من طرف السهم، نسبة إلى حجم خط عنصر القائمة" -#: gtk/gtkmenuitem.c:377 +#: gtk/gtkmenuitem.c:382 msgid "Width in Characters" msgstr "العرض بالحروف" -#: gtk/gtkmenuitem.c:378 +#: gtk/gtkmenuitem.c:383 msgid "The minimum desired width of the menu item in characters" msgstr "الحد الأدنى للعرض المطلوب لعنصر القائمة بالحروف" @@ -3552,14 +3672,6 @@ msgid "" "Whether to put a separator between the message dialog's text and the buttons" msgstr "فيما إذا سيوضع فاصل بين نص حوار الرسالة و الأزرار" -#: gtk/gtkmessagedialog.c:128 -msgid "Message Type" -msgstr "نوع الرسالة" - -#: gtk/gtkmessagedialog.c:129 -msgid "The type of message" -msgstr "نوع الرسالة" - #: gtk/gtkmessagedialog.c:136 msgid "Message Buttons" msgstr "أزرار الرسالة" @@ -3626,23 +3738,23 @@ msgid "" "The amount of space to add on the top and bottom of the widget, in pixels" msgstr "المساحة التي تضاف لأعلى وأسفل الودجة، بالبكسل" -#: gtk/gtkmountoperation.c:139 +#: gtk/gtkmountoperation.c:160 msgid "Parent" msgstr "أب" -#: gtk/gtkmountoperation.c:140 +#: gtk/gtkmountoperation.c:161 msgid "The parent window" msgstr "نافذة الأب" -#: gtk/gtkmountoperation.c:147 +#: gtk/gtkmountoperation.c:168 msgid "Is Showing" msgstr "إظهار" -#: gtk/gtkmountoperation.c:148 +#: gtk/gtkmountoperation.c:169 msgid "Are we showing a dialog" msgstr "هل سنُظهر مربع حوار" -#: gtk/gtkmountoperation.c:156 +#: gtk/gtkmountoperation.c:177 msgid "The screen where this window will be displayed." msgstr "الشاشة التي ستعرض فيها هذه النافذة" @@ -3932,7 +4044,7 @@ msgstr "تقليص" msgid "If TRUE, the child can be made smaller than its requisition" msgstr "إذا ضبط لـ TRUE، فيمكن جعل الإبن أصغر من إستدعائه" -#: gtk/gtkplug.c:150 gtk/gtkstatusicon.c:309 +#: gtk/gtkplug.c:150 gtk/gtkstatusicon.c:312 msgid "Embedded" msgstr "مدمج" @@ -4061,11 +4173,11 @@ msgstr "إعدادات" msgid "Printer settings" msgstr "إعدادات الطابعة" -#: gtk/gtkprintjob.c:143 gtk/gtkprintjob.c:144 gtk/gtkprintunixdialog.c:266 +#: gtk/gtkprintjob.c:143 gtk/gtkprintjob.c:144 gtk/gtkprintunixdialog.c:302 msgid "Page Setup" msgstr "إعداد الصفحة" -#: gtk/gtkprintjob.c:152 gtk/gtkprintoperation.c:1056 +#: gtk/gtkprintjob.c:152 gtk/gtkprintoperation.c:1082 msgid "Track Print Status" msgstr "متابعة حالة الطبع" @@ -4077,51 +4189,51 @@ msgstr "" "صحيح اذا شغل الطبع سيظل يبعث إشارات تغيير الحالة بعد ارسال بيانات الطبع " "لخادوم الطباعة." -#: gtk/gtkprintoperation.c:928 +#: gtk/gtkprintoperation.c:954 msgid "Default Page Setup" msgstr "إعداد الصفحة الإفتراضي" -#: gtk/gtkprintoperation.c:929 +#: gtk/gtkprintoperation.c:955 msgid "The GtkPageSetup used by default" msgstr "الـ GtkPageSetup المستعمل افتراضيا" -#: gtk/gtkprintoperation.c:947 gtk/gtkprintunixdialog.c:284 +#: gtk/gtkprintoperation.c:973 gtk/gtkprintunixdialog.c:320 msgid "Print Settings" msgstr "إعدادات الطبع" -#: gtk/gtkprintoperation.c:948 gtk/gtkprintunixdialog.c:285 +#: gtk/gtkprintoperation.c:974 gtk/gtkprintunixdialog.c:321 msgid "The GtkPrintSettings used for initializing the dialog" msgstr "الـ GtkPrintSettings المستعمل لبدأ الحوار" -#: gtk/gtkprintoperation.c:966 +#: gtk/gtkprintoperation.c:992 msgid "Job Name" msgstr "اسم العمل" -#: gtk/gtkprintoperation.c:967 +#: gtk/gtkprintoperation.c:993 msgid "A string used for identifying the print job." msgstr "سلسلة تستخدم لتعريف وظيفة الطبع." -#: gtk/gtkprintoperation.c:991 +#: gtk/gtkprintoperation.c:1017 msgid "Number of Pages" msgstr "عدد الصفحات" -#: gtk/gtkprintoperation.c:992 +#: gtk/gtkprintoperation.c:1018 msgid "The number of pages in the document." msgstr "عدد الصفحات في المستند" -#: gtk/gtkprintoperation.c:1013 gtk/gtkprintunixdialog.c:274 +#: gtk/gtkprintoperation.c:1039 gtk/gtkprintunixdialog.c:310 msgid "Current Page" msgstr "الصفحة الحالية" -#: gtk/gtkprintoperation.c:1014 gtk/gtkprintunixdialog.c:275 +#: gtk/gtkprintoperation.c:1040 gtk/gtkprintunixdialog.c:311 msgid "The current page in the document" msgstr "الصفحة الحالية في المستند" -#: gtk/gtkprintoperation.c:1035 +#: gtk/gtkprintoperation.c:1061 msgid "Use full page" msgstr "استعمل صفحة كاملة" -#: gtk/gtkprintoperation.c:1036 +#: gtk/gtkprintoperation.c:1062 msgid "" "TRUE if the origin of the context should be at the corner of the page and " "not the corner of the imageable area" @@ -4129,7 +4241,7 @@ msgstr "" "صحيح إذا كان أصل السياق يجب أن يكون في زاوية الصفحة وليس عند زاوية المنطقة " "الصورية" -#: gtk/gtkprintoperation.c:1057 +#: gtk/gtkprintoperation.c:1083 msgid "" "TRUE if the print operation will continue to report on the print job status " "after the print data has been sent to the printer or print server." @@ -4137,106 +4249,129 @@ msgstr "" "صحيح اذا كانت عملية الطبع ستظل تبعث إشارات تغيير الحالة بعد ارسال بيانات " "الطبع لخادوم الطباعة." -#: gtk/gtkprintoperation.c:1074 +#: gtk/gtkprintoperation.c:1100 msgid "Unit" msgstr "الوحدة" -#: gtk/gtkprintoperation.c:1075 +#: gtk/gtkprintoperation.c:1101 msgid "The unit in which distances can be measured in the context" msgstr "الوحدة في المسافات التي يمكن قياسها" -#: gtk/gtkprintoperation.c:1092 +#: gtk/gtkprintoperation.c:1118 msgid "Show Dialog" msgstr "اظهر الحوار" -#: gtk/gtkprintoperation.c:1093 +#: gtk/gtkprintoperation.c:1119 msgid "TRUE if a progress dialog is shown while printing." msgstr "صحيح إذا كان حوار التقدم معروضا عند الطبع" -#: gtk/gtkprintoperation.c:1116 +#: gtk/gtkprintoperation.c:1142 msgid "Allow Async" msgstr "اسمح بـ Async" -#: gtk/gtkprintoperation.c:1117 +#: gtk/gtkprintoperation.c:1143 msgid "TRUE if print process may run asynchronous." msgstr "صحيح اذا يتم تشغيل تطبيق الطباعة لا تزامنيا" -#: gtk/gtkprintoperation.c:1139 gtk/gtkprintoperation.c:1140 +#: gtk/gtkprintoperation.c:1165 gtk/gtkprintoperation.c:1166 msgid "Export filename" msgstr "صدّر اسم الملف" -#: gtk/gtkprintoperation.c:1154 +#: gtk/gtkprintoperation.c:1180 msgid "Status" msgstr "الحالة" -#: gtk/gtkprintoperation.c:1155 +#: gtk/gtkprintoperation.c:1181 msgid "The status of the print operation" msgstr "حالة عملية الطباعة" -#: gtk/gtkprintoperation.c:1175 +#: gtk/gtkprintoperation.c:1201 msgid "Status String" msgstr "نص الحالة" -#: gtk/gtkprintoperation.c:1176 +#: gtk/gtkprintoperation.c:1202 msgid "A human-readable description of the status" msgstr "وصف للحالة بصورة مفهومة للبشر" -#: gtk/gtkprintoperation.c:1194 +#: gtk/gtkprintoperation.c:1220 msgid "Custom tab label" msgstr "عنوان لسان مخصص" -#: gtk/gtkprintoperation.c:1195 +#: gtk/gtkprintoperation.c:1221 msgid "Label for the tab containing custom widgets." msgstr "تسمية اللسان المحتوي على القطع المخصصة" -#: gtk/gtkprintoperation.c:1210 gtk/gtkprintunixdialog.c:309 +#: gtk/gtkprintoperation.c:1236 gtk/gtkprintunixdialog.c:345 #, fuzzy msgid "Support Selection" msgstr "اختيار اللون" -#: gtk/gtkprintoperation.c:1211 +#: gtk/gtkprintoperation.c:1237 msgid "TRUE if the print operation will support print of selection." msgstr "" -#: gtk/gtkprintoperation.c:1227 gtk/gtkprintunixdialog.c:317 +#: gtk/gtkprintoperation.c:1253 gtk/gtkprintunixdialog.c:353 #, fuzzy msgid "Has Selection" msgstr "له اختيار" -#: gtk/gtkprintoperation.c:1228 +#: gtk/gtkprintoperation.c:1254 msgid "TRUE if a selecion exists." msgstr "" -#: gtk/gtkprintunixdialog.c:267 +#: gtk/gtkprintoperation.c:1269 gtk/gtkprintunixdialog.c:361 +#, fuzzy +msgid "Embed Page Setup" +msgstr "إعداد الصفحة" + +#: gtk/gtkprintoperation.c:1270 +msgid "TRUE if page setup combos are embedded in GtkPrintDialog" +msgstr "" + +#: gtk/gtkprintoperation.c:1291 +#, fuzzy +msgid "Number of Pages To Print" +msgstr "عدد الصفحات" + +#: gtk/gtkprintoperation.c:1292 +#, fuzzy +msgid "The number of pages that will be printed." +msgstr "عدد الصفحات في المستند" + +#: gtk/gtkprintunixdialog.c:303 msgid "The GtkPageSetup to use" msgstr "الـ GtkPageSetup المستخدم" -#: gtk/gtkprintunixdialog.c:292 +#: gtk/gtkprintunixdialog.c:328 msgid "Selected Printer" msgstr "الطابعة المنتقاة" -#: gtk/gtkprintunixdialog.c:293 +#: gtk/gtkprintunixdialog.c:329 msgid "The GtkPrinter which is selected" msgstr "الـ GtkPrinter المختار" -#: gtk/gtkprintunixdialog.c:300 +#: gtk/gtkprintunixdialog.c:336 msgid "Manual Capabilites" msgstr "" -#: gtk/gtkprintunixdialog.c:301 +#: gtk/gtkprintunixdialog.c:337 msgid "Capabilities the application can handle" msgstr "" -#: gtk/gtkprintunixdialog.c:310 +#: gtk/gtkprintunixdialog.c:346 #, fuzzy msgid "Whether the dialog supports selection" msgstr "فيما إذا سترسم العلامة في الخط المنتقى" -#: gtk/gtkprintunixdialog.c:318 +#: gtk/gtkprintunixdialog.c:354 #, fuzzy msgid "Whether the application has a selection" msgstr "فيما إذا كانت العملية مفعلة." +#: gtk/gtkprintunixdialog.c:362 +msgid "TRUE if page setup combos are embedded in GtkPrintUnixDialog" +msgstr "" + #: gtk/gtkprogress.c:102 msgid "Activity mode" msgstr "نمط النشاط" @@ -4779,11 +4914,11 @@ msgid "" "Display a second forward arrow button on the opposite end of the scrollbar" msgstr "اعرض زر سهم تقدّم ثان عند النهاية المعاكسة لعمود التدرج" -#: gtk/gtkscrolledwindow.c:218 gtk/gtktext.c:545 gtk/gtktreeview.c:578 +#: gtk/gtkscrolledwindow.c:218 gtk/gtktext.c:545 gtk/gtktreeview.c:569 msgid "Horizontal Adjustment" msgstr "ضبط أفقي" -#: gtk/gtkscrolledwindow.c:225 gtk/gtktext.c:553 gtk/gtktreeview.c:586 +#: gtk/gtkscrolledwindow.c:225 gtk/gtktext.c:553 gtk/gtktreeview.c:577 msgid "Vertical Adjustment" msgstr "ضبط عمودي" @@ -5305,22 +5440,22 @@ msgstr "مكّن التلميحات" msgid "Whether tooltips should be shown on widgets" msgstr "فيما إذا كانت التلميحات ستعرض على الودجات" -#: gtk/gtksizegroup.c:293 +#: gtk/gtksizegroup.c:301 msgid "Mode" msgstr "النسق" -#: gtk/gtksizegroup.c:294 +#: gtk/gtksizegroup.c:302 msgid "" "The directions in which the size group affects the requested sizes of its " "component widgets" msgstr "" "الاتجاه الذي تؤثر فيه مجموعة الحجم على الحجوم المطلوبة للودجات المكونة لها" -#: gtk/gtksizegroup.c:310 +#: gtk/gtksizegroup.c:318 msgid "Ignore hidden" msgstr "أهمل المخفي" -#: gtk/gtksizegroup.c:311 +#: gtk/gtksizegroup.c:319 msgid "" "If TRUE, unmapped widgets are ignored when determining the size of the group" msgstr "اذا كان صحيحاً ، يتم تجاهل القطع غير المرسومة عند تحديد حجم المجموعة" @@ -5388,60 +5523,65 @@ msgstr "فيما إذا كان لعمود الحالة " msgid "Style of bevel around the statusbar text" msgstr "أسلوب الحافة حول نص عمود الحالة" -#: gtk/gtkstatusicon.c:268 +#: gtk/gtkstatusicon.c:271 msgid "The size of the icon" msgstr "حجم الأيقونة" -#: gtk/gtkstatusicon.c:278 +#: gtk/gtkstatusicon.c:281 msgid "The screen where this status icon will be displayed" msgstr "الشاشة التي ستعرض فيها ايقونة الحالة" -#: gtk/gtkstatusicon.c:285 +#: gtk/gtkstatusicon.c:288 msgid "Blinking" msgstr "ومّاض" -#: gtk/gtkstatusicon.c:286 +#: gtk/gtkstatusicon.c:289 msgid "Whether or not the status icon is blinking" msgstr "فيما إذا كانت أيقونة الحالة وامضة" -#: gtk/gtkstatusicon.c:294 +#: gtk/gtkstatusicon.c:297 msgid "Whether or not the status icon is visible" msgstr "فيما إذا كانت أيقونة الحالة مرئية." -#: gtk/gtkstatusicon.c:310 +#: gtk/gtkstatusicon.c:313 msgid "Whether or not the status icon is embedded" msgstr "فيما إذا كانت أيقونة الحالة داخلية" -#: gtk/gtkstatusicon.c:326 gtk/gtktrayicon-x11.c:111 +#: gtk/gtkstatusicon.c:329 gtk/gtktrayicon-x11.c:111 msgid "The orientation of the tray" msgstr "إتجاه الطبق." -#: gtk/gtkstatusicon.c:353 gtk/gtkwidget.c:632 +#: gtk/gtkstatusicon.c:356 gtk/gtkwidget.c:634 msgid "Has tooltip" msgstr "له تلميحة" -#: gtk/gtkstatusicon.c:354 +#: gtk/gtkstatusicon.c:357 #, fuzzy msgid "Whether this tray icon has a tooltip" msgstr "إذا كان لهذه الودجة تلميحة" -#: gtk/gtkstatusicon.c:375 gtk/gtkwidget.c:653 +#: gtk/gtkstatusicon.c:382 gtk/gtkwidget.c:655 msgid "Tooltip Text" msgstr "نص التلميحة" -#: gtk/gtkstatusicon.c:376 gtk/gtkwidget.c:654 gtk/gtkwidget.c:675 +#: gtk/gtkstatusicon.c:383 gtk/gtkwidget.c:656 gtk/gtkwidget.c:677 msgid "The contents of the tooltip for this widget" msgstr "نص تلميحة لهذه الودجة" -#: gtk/gtkstatusicon.c:399 gtk/gtkwidget.c:674 +#: gtk/gtkstatusicon.c:406 gtk/gtkwidget.c:676 msgid "Tooltip markup" msgstr "خصائص التلميحة " -#: gtk/gtkstatusicon.c:400 +#: gtk/gtkstatusicon.c:407 #, fuzzy msgid "The contents of the tooltip for this tray icon" msgstr "نص تلميحة لهذه الودجة" +#: gtk/gtkstatusicon.c:425 +#, fuzzy +msgid "The title of this tray icon" +msgstr "حجم الأيقونة" + #: gtk/gtktable.c:129 msgid "Rows" msgstr "سطور" @@ -5707,7 +5847,7 @@ msgstr "" "التيمات الخ مما يجعله موصى به. يحدّد بانكو بعض المقاييس مثل " "PANGO_SCALE_X_LARGE" -#: gtk/gtktexttag.c:360 gtk/gtktextview.c:591 +#: gtk/gtktexttag.c:360 gtk/gtktextview.c:592 msgid "Left, right, or center justification" msgstr "ضبط لليسار أو لليمين أو للوسط" @@ -5723,7 +5863,7 @@ msgstr "" msgid "Left margin" msgstr "الهامش ا?يسر" -#: gtk/gtktexttag.c:387 gtk/gtktextview.c:600 +#: gtk/gtktexttag.c:387 gtk/gtktextview.c:601 msgid "Width of the left margin in pixels" msgstr "عرض الهامش ا?يسر بالبكسل" @@ -5731,15 +5871,15 @@ msgstr "عرض الهامش ا?يسر بالبكسل" msgid "Right margin" msgstr "الهامش ا?يمن" -#: gtk/gtktexttag.c:397 gtk/gtktextview.c:610 +#: gtk/gtktexttag.c:397 gtk/gtktextview.c:611 msgid "Width of the right margin in pixels" msgstr "عرض الهامش ا?يمن بالبكسل" -#: gtk/gtktexttag.c:407 gtk/gtktextview.c:619 +#: gtk/gtktexttag.c:407 gtk/gtktextview.c:620 msgid "Indent" msgstr "إزاحة" -#: gtk/gtktexttag.c:408 gtk/gtktextview.c:620 +#: gtk/gtktexttag.c:408 gtk/gtktextview.c:621 msgid "Amount to indent the paragraph, in pixels" msgstr "مقدار إزاحة الفقرات، بالبكسل" @@ -5755,7 +5895,7 @@ msgstr "" msgid "Pixels above lines" msgstr "بكسلات أعلى ا?سطر" -#: gtk/gtktexttag.c:429 gtk/gtktextview.c:544 +#: gtk/gtktexttag.c:429 gtk/gtktextview.c:545 msgid "Pixels of blank space above paragraphs" msgstr "بكسلات من المسافات الفارغة أعلى الفقرات" @@ -5763,7 +5903,7 @@ msgstr "بكسلات من المسافات الفارغة أعلى الفقرا msgid "Pixels below lines" msgstr "بكسلات أسفل ا?سطر" -#: gtk/gtktexttag.c:439 gtk/gtktextview.c:554 +#: gtk/gtktexttag.c:439 gtk/gtktextview.c:555 msgid "Pixels of blank space below paragraphs" msgstr "بكسلات من المسافات الفارغة أسفل الفقرات" @@ -5771,20 +5911,20 @@ msgstr "بكسلات من المسافات الفارغة أسفل الفقرا msgid "Pixels inside wrap" msgstr "بكسلات داخل الالتواء" -#: gtk/gtktexttag.c:449 gtk/gtktextview.c:564 +#: gtk/gtktexttag.c:449 gtk/gtktextview.c:565 msgid "Pixels of blank space between wrapped lines in a paragraph" msgstr "بكسلات من المسافات الفارغة بين ا?سطر الملتوية في فقرة" -#: gtk/gtktexttag.c:476 gtk/gtktextview.c:582 +#: gtk/gtktexttag.c:476 gtk/gtktextview.c:583 msgid "" "Whether to wrap lines never, at word boundaries, or at character boundaries" msgstr "ما إذا لن يتم التواء الأسطر عند حدود الكلمات أو الرموز" -#: gtk/gtktexttag.c:485 gtk/gtktextview.c:629 +#: gtk/gtktexttag.c:485 gtk/gtktextview.c:630 msgid "Tabs" msgstr "الأشرطة" -#: gtk/gtktexttag.c:486 gtk/gtktextview.c:630 +#: gtk/gtktexttag.c:486 gtk/gtktextview.c:631 msgid "Custom tabs for this text" msgstr "أشرطة مخصصة لهذا النص" @@ -5928,63 +6068,63 @@ msgstr "لون خلفية محدّد" msgid "Whether this tag affects the paragraph background color" msgstr "فيما إذا كانت هذه الشارة تؤثر في لون خلفية الفقرة" -#: gtk/gtktextview.c:543 +#: gtk/gtktextview.c:544 msgid "Pixels Above Lines" msgstr "بكسلات فوق ا?سطر" -#: gtk/gtktextview.c:553 +#: gtk/gtktextview.c:554 msgid "Pixels Below Lines" msgstr "بكسلات تحت ا?سطر" -#: gtk/gtktextview.c:563 +#: gtk/gtktextview.c:564 msgid "Pixels Inside Wrap" msgstr "بكسلات داخل الالتواء" -#: gtk/gtktextview.c:581 +#: gtk/gtktextview.c:582 msgid "Wrap Mode" msgstr "نظام الالتواء" -#: gtk/gtktextview.c:599 +#: gtk/gtktextview.c:600 msgid "Left Margin" msgstr "الهامش الأيسر" -#: gtk/gtktextview.c:609 +#: gtk/gtktextview.c:610 msgid "Right Margin" msgstr "الهامش الأيمن" -#: gtk/gtktextview.c:637 +#: gtk/gtktextview.c:638 msgid "Cursor Visible" msgstr "المؤشر مرئي" -#: gtk/gtktextview.c:638 +#: gtk/gtktextview.c:639 msgid "If the insertion cursor is shown" msgstr "ما إذا كان مؤشر ا?دخال سيتم عرضه" -#: gtk/gtktextview.c:645 +#: gtk/gtktextview.c:646 msgid "Buffer" msgstr "ذاكرة وسيطة" -#: gtk/gtktextview.c:646 +#: gtk/gtktextview.c:647 msgid "The buffer which is displayed" msgstr "الذاكرة الوسيطة المعروضة" -#: gtk/gtktextview.c:654 +#: gtk/gtktextview.c:655 msgid "Whether entered text overwrites existing contents" msgstr "فيما إذا سينمّق النص المدخل المحتويات الموجودة" -#: gtk/gtktextview.c:661 +#: gtk/gtktextview.c:662 msgid "Accepts tab" msgstr "تقبل الألسنة" -#: gtk/gtktextview.c:662 +#: gtk/gtktextview.c:663 msgid "Whether Tab will result in a tab character being entered" msgstr "فيما سينتج عن اللسان إدخال رمز لسان" -#: gtk/gtktextview.c:691 +#: gtk/gtktextview.c:692 msgid "Error underline color" msgstr "خطأ في لون التسطير" -#: gtk/gtktextview.c:692 +#: gtk/gtktextview.c:693 msgid "Color with which to draw error-indication underlines" msgstr "اللون الذي يتم به رسم التسطيرات المؤشرة للأخطاء" @@ -6167,7 +6307,7 @@ msgstr "تَبَاعُد الأيقونة" msgid "Spacing in pixels between the icon and label" msgstr "الفراغ بالبكسل بين الأيقونة و الشارة" -#: gtk/gtktoolitem.c:191 +#: gtk/gtktoolitem.c:207 msgid "" "Whether the toolbar item is considered important. When TRUE, toolbar buttons " "show text in GTK_TOOLBAR_BOTH_HORIZ mode" @@ -6175,338 +6315,347 @@ msgstr "" "فيما إذا يعتبر عنصر عمود الأدوات مهمّ. إذا ضبط لـ TRUE فستعرض أورار عمود " "الأدوات النص بنسق GTK_TOOLBAR_BOTH_HORIZ" -#: gtk/gtktreemodelsort.c:274 +#: gtk/gtktreemodelsort.c:278 msgid "TreeModelSort Model" msgstr "نمط ترتيب العرض الشجري" -#: gtk/gtktreemodelsort.c:275 +#: gtk/gtktreemodelsort.c:279 msgid "The model for the TreeModelSort to sort" msgstr "نمط فرز العرض الشجري المستخدم للفرز" -#: gtk/gtktreeview.c:570 +#: gtk/gtktreeview.c:561 msgid "TreeView Model" msgstr "نمط العرض الشجري" -#: gtk/gtktreeview.c:571 +#: gtk/gtktreeview.c:562 msgid "The model for the tree view" msgstr "نمط عرض الشجرة" -#: gtk/gtktreeview.c:579 +#: gtk/gtktreeview.c:570 msgid "Horizontal Adjustment for the widget" msgstr "الضبط الأفقي للودجة" -#: gtk/gtktreeview.c:587 +#: gtk/gtktreeview.c:578 msgid "Vertical Adjustment for the widget" msgstr "الضبط العمودي للودجة" -#: gtk/gtktreeview.c:594 +#: gtk/gtktreeview.c:585 msgid "Headers Visible" msgstr "العناوين مرئية" -#: gtk/gtktreeview.c:595 +#: gtk/gtktreeview.c:586 msgid "Show the column header buttons" msgstr "أظهر أزرار رؤوس العمود" -#: gtk/gtktreeview.c:602 +#: gtk/gtktreeview.c:593 msgid "Headers Clickable" msgstr "الرؤوس قابلة للنقر" -#: gtk/gtktreeview.c:603 +#: gtk/gtktreeview.c:594 msgid "Column headers respond to click events" msgstr "رؤوس العمود تستجيب لأحداث النقر" -#: gtk/gtktreeview.c:610 +#: gtk/gtktreeview.c:601 msgid "Expander Column" msgstr "عمود موسع" -#: gtk/gtktreeview.c:611 +#: gtk/gtktreeview.c:602 msgid "Set the column for the expander column" msgstr "تعين العمود للعمود الموسع" -#: gtk/gtktreeview.c:626 +#: gtk/gtktreeview.c:617 msgid "Rules Hint" msgstr "تلميحة القواعد" -#: gtk/gtktreeview.c:627 +#: gtk/gtktreeview.c:618 msgid "Set a hint to the theme engine to draw rows in alternating colors" msgstr "تعين تلميحة لآلة التيمة حتى ترسم صفوفا بألوان متغايرة" -#: gtk/gtktreeview.c:634 +#: gtk/gtktreeview.c:625 msgid "Enable Search" msgstr "تفعيل البحث" -#: gtk/gtktreeview.c:635 +#: gtk/gtktreeview.c:626 msgid "View allows user to search through columns interactively" msgstr "عرض يسمح للمستخدم بالبحث خلال الأعمدة بتفاعل" -#: gtk/gtktreeview.c:642 +#: gtk/gtktreeview.c:633 msgid "Search Column" msgstr "عمود بحث" -#: gtk/gtktreeview.c:643 +#: gtk/gtktreeview.c:634 #, fuzzy msgid "Model column to search through during interactive search" msgstr "عمود النمط الذي يتم البحث خلاله أثناء البحث خلال الكود" -#: gtk/gtktreeview.c:663 +#: gtk/gtktreeview.c:654 msgid "Fixed Height Mode" msgstr "نسق الارتفاع الثابت" -#: gtk/gtktreeview.c:664 +#: gtk/gtktreeview.c:655 msgid "Speeds up GtkTreeView by assuming that all rows have the same height" msgstr "يسرع GtkTreeView باعتبار جميع الأعمدة ذات إرتفاع موحد" -#: gtk/gtktreeview.c:684 +#: gtk/gtktreeview.c:675 msgid "Hover Selection" msgstr "اختيار الحوم" -#: gtk/gtktreeview.c:685 +#: gtk/gtktreeview.c:676 msgid "Whether the selection should follow the pointer" msgstr "فيما اذا كان المنتقى يتبع المؤشر" -#: gtk/gtktreeview.c:704 +#: gtk/gtktreeview.c:695 msgid "Hover Expand" msgstr "تمديد الحوم" -#: gtk/gtktreeview.c:705 +#: gtk/gtktreeview.c:696 msgid "" "Whether rows should be expanded/collapsed when the pointer moves over them" msgstr "ما إذا وجب توسيع وانهيار الصفوف عندما يقوم المؤشر بتحريكها" -#: gtk/gtktreeview.c:719 +#: gtk/gtktreeview.c:710 msgid "Show Expanders" msgstr "اظهار الموسعات" -#: gtk/gtktreeview.c:720 +#: gtk/gtktreeview.c:711 msgid "View has expanders" msgstr "المظهر له موسعات" -#: gtk/gtktreeview.c:734 +#: gtk/gtktreeview.c:725 msgid "Level Indentation" msgstr "مستوى التثليم" -#: gtk/gtktreeview.c:735 +#: gtk/gtktreeview.c:726 msgid "Extra indentation for each level" msgstr "إزاحة اضافية لكل مستوى" # In french = etirement -#: gtk/gtktreeview.c:744 +#: gtk/gtktreeview.c:735 msgid "Rubber Banding" msgstr "التمديد" -#: gtk/gtktreeview.c:745 +#: gtk/gtktreeview.c:736 msgid "" "Whether to enable selection of multiple items by dragging the mouse pointer" msgstr "ما إذا سيتم السماح بانتقاء عناصر متعددة باستعمال الفأرة" -#: gtk/gtktreeview.c:752 +#: gtk/gtktreeview.c:743 msgid "Enable Grid Lines" msgstr "مكّن خطوط الشبكة" -#: gtk/gtktreeview.c:753 +#: gtk/gtktreeview.c:744 msgid "Whether grid lines should be drawn in the tree view" msgstr "فيما إذا كان سيتم عرض خطوط الشبكة في مظهر الشجرة" -#: gtk/gtktreeview.c:761 +#: gtk/gtktreeview.c:752 msgid "Enable Tree Lines" msgstr "مكّن خطوط الشجرة" -#: gtk/gtktreeview.c:762 +#: gtk/gtktreeview.c:753 msgid "Whether tree lines should be drawn in the tree view" msgstr "فيما إذا كان سيتم عرض خطوط الشجرة في مظهر الشجرة" -#: gtk/gtktreeview.c:770 +#: gtk/gtktreeview.c:761 msgid "The column in the model containing the tooltip texts for the rows" msgstr "عمود النموذج المحتوي على نصوص التلميحات للصفوف" -#: gtk/gtktreeview.c:792 +#: gtk/gtktreeview.c:783 msgid "Vertical Separator Width" msgstr "العرض العمودي للفاصل" -#: gtk/gtktreeview.c:793 +#: gtk/gtktreeview.c:784 msgid "Vertical space between cells. Must be an even number" msgstr "الفراغ العمودي بين الخلايا. يجب أن يكون رقما زوجيا" -#: gtk/gtktreeview.c:801 +#: gtk/gtktreeview.c:792 msgid "Horizontal Separator Width" msgstr "العرض الأفقي للفاصل" -#: gtk/gtktreeview.c:802 +#: gtk/gtktreeview.c:793 msgid "Horizontal space between cells. Must be an even number" msgstr "الفراغ الأفقي بين الخلايا. يجب أن يكون رقما زوجيا" -#: gtk/gtktreeview.c:810 +#: gtk/gtktreeview.c:801 msgid "Allow Rules" msgstr "اسمح بالقواعد" -#: gtk/gtktreeview.c:811 +#: gtk/gtktreeview.c:802 msgid "Allow drawing of alternating color rows" msgstr "السماح برسم أعمدة ملونة متوالية" -#: gtk/gtktreeview.c:817 +#: gtk/gtktreeview.c:808 msgid "Indent Expanders" msgstr "إزاحة الموسعات" -#: gtk/gtktreeview.c:818 +#: gtk/gtktreeview.c:809 msgid "Make the expanders indented" msgstr "جعل الموسعات مجوفة" -#: gtk/gtktreeview.c:824 +#: gtk/gtktreeview.c:815 msgid "Even Row Color" msgstr "لون السطر الزوجي" -#: gtk/gtktreeview.c:825 +#: gtk/gtktreeview.c:816 msgid "Color to use for even rows" msgstr "اللون للاستخدام للسطور الزوجية" -#: gtk/gtktreeview.c:831 +#: gtk/gtktreeview.c:822 msgid "Odd Row Color" msgstr "لون السطر الغريب" -#: gtk/gtktreeview.c:832 +#: gtk/gtktreeview.c:823 msgid "Color to use for odd rows" msgstr "اللون للاستخدام للسطور الغريبة" -#: gtk/gtktreeview.c:838 +#: gtk/gtktreeview.c:829 msgid "Row Ending details" msgstr "تفاصيل نهاية الصف" -#: gtk/gtktreeview.c:839 +#: gtk/gtktreeview.c:830 msgid "Enable extended row background theming" msgstr "تفعيل التنسيق الممدّد لخلفية الأعمدة" -#: gtk/gtktreeview.c:845 +#: gtk/gtktreeview.c:836 msgid "Grid line width" msgstr "عرض خط الشبكة" -#: gtk/gtktreeview.c:846 +#: gtk/gtktreeview.c:837 msgid "Width, in pixels, of the tree view grid lines" msgstr "العرض بالبكسلات لأسطر الشبكة لمظهر الشجرة" -#: gtk/gtktreeview.c:852 +#: gtk/gtktreeview.c:843 msgid "Tree line width" msgstr "عرض سطر الشجرة" -#: gtk/gtktreeview.c:853 +#: gtk/gtktreeview.c:844 msgid "Width, in pixels, of the tree view lines" msgstr "العرض بالبكسلات لأسطر مظهر الشجرة" -#: gtk/gtktreeview.c:859 +#: gtk/gtktreeview.c:850 msgid "Grid line pattern" msgstr "نمط خط الشبكة" -#: gtk/gtktreeview.c:860 +#: gtk/gtktreeview.c:851 msgid "Dash pattern used to draw the tree view grid lines" msgstr "نمط الخط الفاصل لرسم أسطر شبكة مظهر الشجرة" -#: gtk/gtktreeview.c:866 +#: gtk/gtktreeview.c:857 msgid "Tree line pattern" msgstr "نمط سطر الشجرة" -#: gtk/gtktreeview.c:867 +#: gtk/gtktreeview.c:858 msgid "Dash pattern used to draw the tree view lines" msgstr "نمط الخط الفاصل لرسم أسطر مظهر الشجرة" -#: gtk/gtktreeviewcolumn.c:192 +#: gtk/gtktreeviewcolumn.c:193 msgid "Whether to display the column" msgstr "ما إذا يعرض العمود" -#: gtk/gtktreeviewcolumn.c:199 gtk/gtkwindow.c:537 +#: gtk/gtktreeviewcolumn.c:200 gtk/gtkwindow.c:537 msgid "Resizable" msgstr "قابل للتحجيم" -#: gtk/gtktreeviewcolumn.c:200 +#: gtk/gtktreeviewcolumn.c:201 msgid "Column is user-resizable" msgstr "العمود قابل للتحجيم من قبل المستخدم" -#: gtk/gtktreeviewcolumn.c:208 +#: gtk/gtktreeviewcolumn.c:209 msgid "Current width of the column" msgstr "العرض الحالي للعمود" -#: gtk/gtktreeviewcolumn.c:217 +#: gtk/gtktreeviewcolumn.c:218 msgid "Space which is inserted between cells" msgstr "الفراغ الملحق بين الخلايا" -#: gtk/gtktreeviewcolumn.c:225 +#: gtk/gtktreeviewcolumn.c:226 msgid "Sizing" msgstr "تحجيم" -#: gtk/gtktreeviewcolumn.c:226 +#: gtk/gtktreeviewcolumn.c:227 msgid "Resize mode of the column" msgstr "نظام التحجيم للعمود" -#: gtk/gtktreeviewcolumn.c:234 +#: gtk/gtktreeviewcolumn.c:235 msgid "Fixed Width" msgstr "العرض الثابت" -#: gtk/gtktreeviewcolumn.c:235 +#: gtk/gtktreeviewcolumn.c:236 msgid "Current fixed width of the column" msgstr "العرض الحالي الثابت للعمود" -#: gtk/gtktreeviewcolumn.c:244 +#: gtk/gtktreeviewcolumn.c:245 msgid "Minimum Width" msgstr "العرض الأصغر" -#: gtk/gtktreeviewcolumn.c:245 +#: gtk/gtktreeviewcolumn.c:246 msgid "Minimum allowed width of the column" msgstr "العرض الأصغر المسموح به للعمود" -#: gtk/gtktreeviewcolumn.c:254 +#: gtk/gtktreeviewcolumn.c:255 msgid "Maximum Width" msgstr "العرض الأكبر" -#: gtk/gtktreeviewcolumn.c:255 +#: gtk/gtktreeviewcolumn.c:256 msgid "Maximum allowed width of the column" msgstr "العرض الأكبر المسموح به للعمود" -#: gtk/gtktreeviewcolumn.c:265 +#: gtk/gtktreeviewcolumn.c:266 msgid "Title to appear in column header" msgstr "العنوان الذي يتم عرضه في ترويسة العمود" -#: gtk/gtktreeviewcolumn.c:273 +#: gtk/gtktreeviewcolumn.c:274 msgid "Column gets share of extra width allocated to the widget" msgstr "يتلقى العمود قسمته من العرض الإضافي المخصّص للودجة" -#: gtk/gtktreeviewcolumn.c:280 +#: gtk/gtktreeviewcolumn.c:281 msgid "Clickable" msgstr "قابل للنقر" -#: gtk/gtktreeviewcolumn.c:281 +#: gtk/gtktreeviewcolumn.c:282 msgid "Whether the header can be clicked" msgstr "ما إذا كانت الترويسة قابلة للنقر أم لا" -#: gtk/gtktreeviewcolumn.c:289 +#: gtk/gtktreeviewcolumn.c:290 msgid "Widget" msgstr "ودجة" -#: gtk/gtktreeviewcolumn.c:290 +#: gtk/gtktreeviewcolumn.c:291 msgid "Widget to put in column header button instead of column title" msgstr "الودجة التي يتم وضعها في زر ترويسة العمود بدل عنوان العمود" -#: gtk/gtktreeviewcolumn.c:298 +#: gtk/gtktreeviewcolumn.c:299 msgid "X Alignment of the column header text or widget" msgstr "ضبط س لودجة أو نص ترويسة العمود" -#: gtk/gtktreeviewcolumn.c:308 +#: gtk/gtktreeviewcolumn.c:309 msgid "Whether the column can be reordered around the headers" msgstr "إذا ما كان من الممكن أن يعاد ترتيب العمود حول الترويسات" -#: gtk/gtktreeviewcolumn.c:315 +#: gtk/gtktreeviewcolumn.c:316 msgid "Sort indicator" msgstr "مؤشر الفرز" -#: gtk/gtktreeviewcolumn.c:316 +#: gtk/gtktreeviewcolumn.c:317 msgid "Whether to show a sort indicator" msgstr "ما إذا كان سيتم عرض مؤشر الفرز أم لا." -#: gtk/gtktreeviewcolumn.c:323 +#: gtk/gtktreeviewcolumn.c:324 msgid "Sort order" msgstr "ترتيب الفرز" -#: gtk/gtktreeviewcolumn.c:324 +#: gtk/gtktreeviewcolumn.c:325 msgid "Sort direction the sort indicator should indicate" msgstr "اتجاه الفرز الذي يتوجب على مؤشر الفرز أن يشير إليه" +#: gtk/gtktreeviewcolumn.c:341 +#, fuzzy +msgid "Sort column ID" +msgstr "عمود النص" + +#: gtk/gtktreeviewcolumn.c:342 +msgid "Logical sort column ID this column sorts on when selected for sorting" +msgstr "" + #: gtk/gtkuimanager.c:223 msgid "Whether tearoff menu items should be added to menus" msgstr "فيما إذا ستضاف عناصر القوائم القابلة للقطف للقوائم" @@ -6535,205 +6684,215 @@ msgstr "GtkAdjustment المحدّد لقيم الموقع العمودي لمن msgid "Determines how the shadowed box around the viewport is drawn" msgstr "يحدّد كيفيّة رسم الصندوق المضلّل حول منفذ المشهد" -#: gtk/gtkwidget.c:483 +#: gtk/gtkwidget.c:485 msgid "Widget name" msgstr "اسم الودجة" -#: gtk/gtkwidget.c:484 +#: gtk/gtkwidget.c:486 msgid "The name of the widget" msgstr "اسم الودجة" -#: gtk/gtkwidget.c:490 +#: gtk/gtkwidget.c:492 msgid "Parent widget" msgstr "الودجة الأب" -#: gtk/gtkwidget.c:491 +#: gtk/gtkwidget.c:493 msgid "The parent widget of this widget. Must be a Container widget" msgstr "الودجة الأب لهذه الودجة. يجب أن يكون ودجة حاوية" -#: gtk/gtkwidget.c:498 +#: gtk/gtkwidget.c:500 msgid "Width request" msgstr "طلب عرض" -#: gtk/gtkwidget.c:499 +#: gtk/gtkwidget.c:501 msgid "" "Override for width request of the widget, or -1 if natural request should be " "used" msgstr "طلب تنميق لعرض الودجة، أو -1 إذا وجب استخدام طلب اعتيادي" -#: gtk/gtkwidget.c:507 +#: gtk/gtkwidget.c:509 msgid "Height request" msgstr "طلب ارتفاع" -#: gtk/gtkwidget.c:508 +#: gtk/gtkwidget.c:510 msgid "" "Override for height request of the widget, or -1 if natural request should " "be used" msgstr "طلب تنميق لإرتفاع الودجة، أو -1 إذا وجب استخدام طلب اعتيادي" -#: gtk/gtkwidget.c:517 +#: gtk/gtkwidget.c:519 msgid "Whether the widget is visible" msgstr "ما إذا كان الكائن ظاهرا" -#: gtk/gtkwidget.c:524 +#: gtk/gtkwidget.c:526 msgid "Whether the widget responds to input" msgstr "ما إذا كان الكائن يرد على الإدخال" -#: gtk/gtkwidget.c:530 +#: gtk/gtkwidget.c:532 msgid "Application paintable" msgstr "التطبيق قابل للرسم" -#: gtk/gtkwidget.c:531 +#: gtk/gtkwidget.c:533 msgid "Whether the application will paint directly on the widget" msgstr "ما إذا كان التطبيق سيرسم مباشرة على الودجة" -#: gtk/gtkwidget.c:537 +#: gtk/gtkwidget.c:539 msgid "Can focus" msgstr "ممكن تلقي البؤرة" -#: gtk/gtkwidget.c:538 +#: gtk/gtkwidget.c:540 msgid "Whether the widget can accept the input focus" msgstr "ما إذا كان بقدرة الكائن قبول بؤرة الإدخال" -#: gtk/gtkwidget.c:544 +#: gtk/gtkwidget.c:546 msgid "Has focus" msgstr "له بؤرة" -#: gtk/gtkwidget.c:545 +#: gtk/gtkwidget.c:547 msgid "Whether the widget has the input focus" msgstr "ما إذا كان الكائن له بؤرة الإدخال" -#: gtk/gtkwidget.c:551 +#: gtk/gtkwidget.c:553 msgid "Is focus" msgstr "هو تركيز" -#: gtk/gtkwidget.c:552 +#: gtk/gtkwidget.c:554 msgid "Whether the widget is the focus widget within the toplevel" msgstr "ما إذا كانت الودجة هي ودجة التركيز ضمن المستوى الأعلى" -#: gtk/gtkwidget.c:558 +#: gtk/gtkwidget.c:560 msgid "Can default" msgstr "ممكن الافتراض" -#: gtk/gtkwidget.c:559 +#: gtk/gtkwidget.c:561 msgid "Whether the widget can be the default widget" msgstr "ما إذا كانت الودجة ستصبح الودجة الافتراضية" -#: gtk/gtkwidget.c:565 +#: gtk/gtkwidget.c:567 msgid "Has default" msgstr "له افتراض" -#: gtk/gtkwidget.c:566 +#: gtk/gtkwidget.c:568 msgid "Whether the widget is the default widget" msgstr "ما إذا كانت الودجة هي الودجة الافتراضية" -#: gtk/gtkwidget.c:572 +#: gtk/gtkwidget.c:574 msgid "Receives default" msgstr "استقبال الافتراض" -#: gtk/gtkwidget.c:573 +#: gtk/gtkwidget.c:575 msgid "If TRUE, the widget will receive the default action when it is focused" msgstr "إذا كان TRUE، فستتلقى الودجة الحدث الافتراضي عند تركيزها" -#: gtk/gtkwidget.c:579 +#: gtk/gtkwidget.c:581 msgid "Composite child" msgstr "ابن مركب" -#: gtk/gtkwidget.c:580 +#: gtk/gtkwidget.c:582 msgid "Whether the widget is part of a composite widget" msgstr "ما إذا كانت الودجة جزء من ودجة مركبة" -#: gtk/gtkwidget.c:586 +#: gtk/gtkwidget.c:588 msgid "Style" msgstr "نمط" -#: gtk/gtkwidget.c:587 +#: gtk/gtkwidget.c:589 msgid "" "The style of the widget, which contains information about how it will look " "(colors etc)" msgstr "أسلوب الودجة، المحتوية على معلومات حول مظهرها (الألوان الخ)" -#: gtk/gtkwidget.c:593 +#: gtk/gtkwidget.c:595 msgid "Events" msgstr "أحداث" -#: gtk/gtkwidget.c:594 +#: gtk/gtkwidget.c:596 msgid "The event mask that decides what kind of GdkEvents this widget gets" msgstr "غلاف الأحداث الدي يحدّد أي نوع من GdkEvents ستتلقى هذه الودجة" -#: gtk/gtkwidget.c:601 +#: gtk/gtkwidget.c:603 msgid "Extension events" msgstr "أحداث امتداد" -#: gtk/gtkwidget.c:602 +#: gtk/gtkwidget.c:604 msgid "The mask that decides what kind of extension events this widget gets" msgstr "الغلاف الذي يحدّد أي إمتدادات الأحداث ستتلقّى هذه الودجة" -#: gtk/gtkwidget.c:609 +#: gtk/gtkwidget.c:611 msgid "No show all" msgstr "لا عرض للكل" -#: gtk/gtkwidget.c:610 +#: gtk/gtkwidget.c:612 msgid "Whether gtk_widget_show_all() should not affect this widget" msgstr "فيما إذا لن يؤثّر gtk_widget_show_all() هذه الودجة" -#: gtk/gtkwidget.c:633 +#: gtk/gtkwidget.c:635 msgid "Whether this widget has a tooltip" msgstr "إذا كان لهذه الودجة تلميحة" -#: gtk/gtkwidget.c:689 +#: gtk/gtkwidget.c:691 msgid "Window" msgstr "نافذة" -#: gtk/gtkwidget.c:690 +#: gtk/gtkwidget.c:692 msgid "The widget's window if it is realized" msgstr "نافذة الودجة عند تحقيقها" -#: gtk/gtkwidget.c:2212 +#: gtk/gtkwidget.c:706 +#, fuzzy +msgid "Double Buffered" +msgstr "ذاكرة وسيطة" + +#: gtk/gtkwidget.c:707 +#, fuzzy +msgid "Whether or not the widget is double buffered" +msgstr "اذا كان الملحق داخليا" + +#: gtk/gtkwidget.c:2229 msgid "Interior Focus" msgstr "بؤرة داخلية" -#: gtk/gtkwidget.c:2213 +#: gtk/gtkwidget.c:2230 msgid "Whether to draw the focus indicator inside widgets" msgstr "ما إذا يرسم مؤشر التركيز داخل الودجات" -#: gtk/gtkwidget.c:2219 +#: gtk/gtkwidget.c:2236 msgid "Focus linewidth" msgstr "عرض خط البؤرة" -#: gtk/gtkwidget.c:2220 +#: gtk/gtkwidget.c:2237 msgid "Width, in pixels, of the focus indicator line" msgstr "العرض بالبكسلات لسطر مؤشر التركيز" -#: gtk/gtkwidget.c:2226 +#: gtk/gtkwidget.c:2243 msgid "Focus line dash pattern" msgstr "خط البؤرة بالنقش المتقطع" -#: gtk/gtkwidget.c:2227 +#: gtk/gtkwidget.c:2244 msgid "Dash pattern used to draw the focus indicator" msgstr "نمط الخط الفاصل المستعمل لرسم مؤشر التكيز" -#: gtk/gtkwidget.c:2232 +#: gtk/gtkwidget.c:2249 msgid "Focus padding" msgstr "حشو البؤرة" -#: gtk/gtkwidget.c:2233 +#: gtk/gtkwidget.c:2250 msgid "Width, in pixels, between focus indicator and the widget 'box'" msgstr "العرض بالبكسلات بين مؤشر التركيز و ودجة 'صندوق'" -#: gtk/gtkwidget.c:2238 +#: gtk/gtkwidget.c:2255 msgid "Cursor color" msgstr "لون المؤشر" -#: gtk/gtkwidget.c:2239 +#: gtk/gtkwidget.c:2256 msgid "Color with which to draw insertion cursor" msgstr "اللون الذي يتم به رسم مؤشر ا?دخال" -#: gtk/gtkwidget.c:2244 +#: gtk/gtkwidget.c:2261 msgid "Secondary cursor color" msgstr "مؤشر ا?دخال الثانوي" -#: gtk/gtkwidget.c:2245 +#: gtk/gtkwidget.c:2262 msgid "" "Color with which to draw the secondary insertion cursor when editing mixed " "right-to-left and left-to-right text" @@ -6741,77 +6900,77 @@ msgstr "" "اللون الذي سيرسم يه مؤشر الإدخال الثانوي عند تحرير نص مختلط من اليمين إلى " "اليسار و من اليسار إلى اليمين" -#: gtk/gtkwidget.c:2250 +#: gtk/gtkwidget.c:2267 msgid "Cursor line aspect ratio" msgstr "نسبة الطول للعرض لمؤشر السطر" -#: gtk/gtkwidget.c:2251 +#: gtk/gtkwidget.c:2268 msgid "Aspect ratio with which to draw insertion cursor" msgstr "نسبة الطول للعرض التي سيرسم بها مؤشر إدخال." -#: gtk/gtkwidget.c:2265 +#: gtk/gtkwidget.c:2282 msgid "Draw Border" msgstr "ارسم الحدّ" -#: gtk/gtkwidget.c:2266 +#: gtk/gtkwidget.c:2283 msgid "Size of areas outside the widget's allocation to draw" msgstr "حجم المساحات المرسومة خارج مكان الودجة " -#: gtk/gtkwidget.c:2279 +#: gtk/gtkwidget.c:2296 msgid "Unvisited Link Color" msgstr "لون الوصلة غير المزارة" -#: gtk/gtkwidget.c:2280 +#: gtk/gtkwidget.c:2297 msgid "Color of unvisited links" msgstr "لون الوصلات غير المزارة" -#: gtk/gtkwidget.c:2293 +#: gtk/gtkwidget.c:2310 msgid "Visited Link Color" msgstr "لون الوصلة المزارة" -#: gtk/gtkwidget.c:2294 +#: gtk/gtkwidget.c:2311 msgid "Color of visited links" msgstr "لون الوصلات المزارة" -#: gtk/gtkwidget.c:2308 +#: gtk/gtkwidget.c:2325 msgid "Wide Separators" msgstr "فواصل عريضة" -#: gtk/gtkwidget.c:2309 +#: gtk/gtkwidget.c:2326 msgid "" "Whether separators have configurable width and should be drawn using a box " "instead of a line" msgstr "إذا كان للفواصل عرض متغير مرسوم باستعمال علبة عوضا عن خط" -#: gtk/gtkwidget.c:2323 +#: gtk/gtkwidget.c:2340 msgid "Separator Width" msgstr "عرض الفاصل" -#: gtk/gtkwidget.c:2324 +#: gtk/gtkwidget.c:2341 msgid "The width of separators if wide-separators is TRUE" msgstr "عرض الفواصل إذا كان wide-separators محددا بـ TRUE" -#: gtk/gtkwidget.c:2338 +#: gtk/gtkwidget.c:2355 msgid "Separator Height" msgstr "ارتفاع الفاصل" -#: gtk/gtkwidget.c:2339 +#: gtk/gtkwidget.c:2356 msgid "The height of separators if \"wide-separators\" is TRUE" msgstr "ارتفاع الفواصل إذا كان \"wide-separators\" محددا بـ TRUE" -#: gtk/gtkwidget.c:2353 +#: gtk/gtkwidget.c:2370 msgid "Horizontal Scroll Arrow Length" msgstr "طول أسهم شريط التدرج الأفقي" -#: gtk/gtkwidget.c:2354 +#: gtk/gtkwidget.c:2371 msgid "The length of horizontal scroll arrows" msgstr "طول أسهم شريط التدرج الأفقي" -#: gtk/gtkwidget.c:2368 +#: gtk/gtkwidget.c:2385 msgid "Vertical Scroll Arrow Length" msgstr "طول أسهم شريط التدرج العمودي" -#: gtk/gtkwidget.c:2369 +#: gtk/gtkwidget.c:2386 msgid "The length of vertical scroll arrows" msgstr "عرض أسهم شريط التدرج العمودي" diff --git a/po-properties/as.po b/po-properties/as.po index 06f3c30cd8..22c6a69d7c 100644 --- a/po-properties/as.po +++ b/po-properties/as.po @@ -9,16 +9,24 @@ msgid "" msgstr "" "Project-Id-Version: as\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-06-15 20:53-0400\n" -"PO-Revision-Date: 2009-03-16 17:51+0530\n" -"Last-Translator: Amitakhya Phukan \n" -"Language-Team: American English \n" +"POT-Creation-Date: 2009-09-30 17:31-0400\n" +"PO-Revision-Date: 2009-09-16 11:40+0530\n" +"Last-Translator: \n" +"Language-Team: American English <>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Lokalize 0.3\n" +"X-Generator: Lokalize 0.2\n" "Plural-Forms: nplurals=2; plural=(n!=1)\n" +#: gdk-pixbuf/gdk-pixbuf-simple-anim.c:165 +msgid "Loop" +msgstr "লুপ" + +#: gdk-pixbuf/gdk-pixbuf-simple-anim.c:166 +msgid "Whether the animation should loop when it reaches the end" +msgstr "পইন্টাৰক অনুসৰণ কৰি নিৰ্বাচন কৰা হ'ব নে নাই" + #: gdk-pixbuf/gdk-pixbuf.c:89 msgid "Number of Channels" msgstr "চেনেলৰ সংখ্যা " @@ -51,7 +59,7 @@ msgstr "প্ৰতিটো নমুনাৰ বাবে বিট" msgid "The number of bits per sample" msgstr "প্ৰতিটো নমুনাৰ বাবে বিটৰ সংখ্যা" -#: gdk-pixbuf/gdk-pixbuf.c:132 gtk/gtklayout.c:632 gtk/gtktreeviewcolumn.c:207 +#: gdk-pixbuf/gdk-pixbuf.c:132 gtk/gtklayout.c:632 gtk/gtktreeviewcolumn.c:208 msgid "Width" msgstr "বহল" @@ -92,12 +100,12 @@ msgstr "অবিকল্পিত প্ৰদৰ্শন" msgid "The default display for GDK" msgstr "GDK ৰ অবিকল্পিত প্ৰদৰ্শন" -#: gdk/gdkpango.c:537 gtk/gtkinvisible.c:86 gtk/gtkmountoperation.c:155 -#: gtk/gtkstatusicon.c:277 gtk/gtkwindow.c:614 +#: gdk/gdkpango.c:538 gtk/gtkinvisible.c:86 gtk/gtkmountoperation.c:176 +#: gtk/gtkstatusicon.c:280 gtk/gtkwindow.c:614 msgid "Screen" msgstr "পৰ্দ্দা" -#: gdk/gdkpango.c:538 +#: gdk/gdkpango.c:539 msgid "the GdkScreen for the renderer" msgstr "ৰেন্ডাৰাৰৰ বাবে GdkScreen" @@ -117,6 +125,10 @@ msgstr "ফন্টৰ বিভাজন" msgid "The resolution for fonts on the screen" msgstr "পৰ্দ্দাৰ ফন্টৰ বিভাজন" +#: gdk/gdkwindow.c:472 gdk/gdkwindow.c:473 +msgid "Cursor" +msgstr "কাৰ্ছাৰ" + #: gtk/gtkaboutdialog.c:239 msgid "Program name" msgstr "অনুপ্ৰয়োগৰ নাম" @@ -203,7 +215,7 @@ msgstr "অমিতাক্ষ ফুকন (aphukan@fedoraproject.org)" #: gtk/gtkaboutdialog.c:409 msgid "" "Credits to the translators. This string should be marked as translatable" -msgstr "অনুবাদকদের স্বীকৃতি। এই পংক্তিটি অনুবাদযোগ্য রূপে চিহ্নিত হওয়া আবশ্যক।" +msgstr "অনুবাদকদেৰ স্বীকৃতি। এই পংক্তিটি অনুবাদযোগ্য ৰূপে চিহ্নিত হওয়া আবশ্যক।" #: gtk/gtkaboutdialog.c:424 msgid "Logo" @@ -259,7 +271,7 @@ msgid "A unique name for the action." msgstr "এই কামৰ বাবে এটা অদ্বিতীয় নাম ।" #: gtk/gtkaction.c:198 gtk/gtkbutton.c:219 gtk/gtkexpander.c:195 -#: gtk/gtkframe.c:105 gtk/gtklabel.c:495 gtk/gtkmenuitem.c:300 +#: gtk/gtkframe.c:105 gtk/gtklabel.c:496 gtk/gtkmenuitem.c:305 #: gtk/gtktoolbutton.c:202 msgid "Label" msgstr "লেবেল" @@ -292,30 +304,30 @@ msgstr "Stock আইকন" msgid "The stock icon displayed in widgets representing this action." msgstr "বিভিন্ন উইজেটত এই কাম নিৰ্দেশকাৰী Stock আইকন।" -#: gtk/gtkaction.c:261 gtk/gtkstatusicon.c:250 +#: gtk/gtkaction.c:261 gtk/gtkstatusicon.c:253 msgid "GIcon" msgstr "GIcon" #: gtk/gtkaction.c:262 gtk/gtkcellrendererpixbuf.c:206 gtk/gtkimage.c:248 -#: gtk/gtkstatusicon.c:251 +#: gtk/gtkstatusicon.c:254 msgid "The GIcon being displayed" msgstr "প্ৰদৰ্শন কৰা GIcon" #: gtk/gtkaction.c:282 gtk/gtkcellrendererpixbuf.c:171 gtk/gtkimage.c:230 -#: gtk/gtkprinter.c:172 gtk/gtkstatusicon.c:234 gtk/gtkwindow.c:606 +#: gtk/gtkprinter.c:172 gtk/gtkstatusicon.c:237 gtk/gtkwindow.c:606 msgid "Icon Name" msgstr "আইকনৰ নাম" #: gtk/gtkaction.c:283 gtk/gtkcellrendererpixbuf.c:172 gtk/gtkimage.c:231 -#: gtk/gtkstatusicon.c:235 +#: gtk/gtkstatusicon.c:238 msgid "The name of the icon from the icon theme" msgstr "আইকন থিমৰ পৰা প্ৰাপ্ত আইকনৰ নাম" -#: gtk/gtkaction.c:290 gtk/gtktoolitem.c:176 +#: gtk/gtkaction.c:290 gtk/gtktoolitem.c:192 msgid "Visible when horizontal" msgstr "পথালিকে দেখা দিয়া" -#: gtk/gtkaction.c:291 gtk/gtktoolitem.c:177 +#: gtk/gtkaction.c:291 gtk/gtktoolitem.c:193 msgid "" "Whether the toolbar item is visible when the toolbar is in a horizontal " "orientation." @@ -331,17 +343,17 @@ msgid "" "overflow menu." msgstr "TRUE হ'লে, টুলবাৰ overflow তালিকাত এই কামৰ টুল আইটেমৰ নিযুক্তকক দেখুৱা হয় ।" -#: gtk/gtkaction.c:314 gtk/gtktoolitem.c:183 +#: gtk/gtkaction.c:314 gtk/gtktoolitem.c:199 msgid "Visible when vertical" msgstr "উলম্ব অৱস্থাত দৃশ্যমান" -#: gtk/gtkaction.c:315 gtk/gtktoolitem.c:184 +#: gtk/gtkaction.c:315 gtk/gtktoolitem.c:200 msgid "" "Whether the toolbar item is visible when the toolbar is in a vertical " "orientation." msgstr "টুলবাৰ উলম্ব অৱস্থাত থাকিলে টুলবাৰৰ বস্তু দৃশ্যমান থাকিব নে নাই ।" -#: gtk/gtkaction.c:322 gtk/gtktoolitem.c:190 +#: gtk/gtkaction.c:322 gtk/gtktoolitem.c:206 msgid "Is important" msgstr "গুৰুত্বপূৰ্ণ হয়" @@ -351,7 +363,7 @@ msgid "" "this action show text in GTK_TOOLBAR_BOTH_HORIZ mode." msgstr "" "কামটোক গুৰুত্বপূৰ্ণ বিবেচনা কৰা হয় নে নহয় । ইয়াৰ মান TRUE হ'লে টুল-আইটেম নিযুক্তক " -"GTK_TOOLBAR_BOTH_HORIZ মোডত লিপি প্ৰদৰ্শন কৰে ।" +"GTK_TOOLBAR_BOTH_HORIZ মোডত লিপি প্ৰদৰ্শন কৰি ।" #: gtk/gtkaction.c:331 msgid "Hide if empty" @@ -362,7 +374,7 @@ msgid "When TRUE, empty menu proxies for this action are hidden." msgstr "TRUE হ'লে এই কামৰ ৰিক্ত তালিকা নিযুক্তকক লুকাই ৰখা হয় ।" #: gtk/gtkaction.c:338 gtk/gtkactiongroup.c:177 gtk/gtkcellrenderer.c:193 -#: gtk/gtkwidget.c:523 +#: gtk/gtkwidget.c:525 msgid "Sensitive" msgstr "সংবেদনশীল" @@ -370,8 +382,8 @@ msgstr "সংবেদনশীল" msgid "Whether the action is enabled." msgstr "কামটো সক্ৰিয় হয় নে নহয়" -#: gtk/gtkaction.c:345 gtk/gtkactiongroup.c:184 gtk/gtkstatusicon.c:293 -#: gtk/gtktreeviewcolumn.c:191 gtk/gtkwidget.c:516 +#: gtk/gtkaction.c:345 gtk/gtkactiongroup.c:184 gtk/gtkstatusicon.c:296 +#: gtk/gtktreeviewcolumn.c:192 gtk/gtkwidget.c:518 msgid "Visible" msgstr "দৃশ্যমান" @@ -403,6 +415,22 @@ msgstr "এই কামৰ গোট সক্ৰিয় নে নহয় ।" msgid "Whether the action group is visible." msgstr "এই কামৰ গোট দৃশ্যমান নে নহয় ।" +#: gtk/gtkactivatable.c:304 +msgid "Related Action" +msgstr "সম্বন্ধিত কাম" + +#: gtk/gtkactivatable.c:305 +msgid "The action this activatable will activate and receive updates from" +msgstr "এই সক্ৰিয় কৰিব পৰা বস্তুয়ে সক্ৰিয় আৰু উন্নয়ন গ্ৰহণ কৰিব পৰা কাৰ্য্যটো" + +#: gtk/gtkactivatable.c:327 +msgid "Use Action Appearance" +msgstr "কাৰ্য্যৰ প্ৰদৰ্শন ব্যৱহাৰ কৰক" + +#: gtk/gtkactivatable.c:328 +msgid "Whether to use the related actions appearance properties" +msgstr "সম্বন্ধিত কাৰ্য্যৰ প্ৰদৰ্শনৰ গুণ ব্যৱহাৰ কৰা যাব নে নাই" + #: gtk/gtkadjustment.c:93 gtk/gtkcellrendererprogress.c:128 #: gtk/gtkscalebutton.c:206 gtk/gtkspinbutton.c:269 msgid "Value" @@ -550,7 +578,7 @@ msgstr "নিৰ্দেশকৰ ছাঁ" msgid "Appearance of the shadow surrounding the arrow" msgstr "কাঁড় চিহ্নৰ কাষত থকা ছাঁৰ চেহেৰা" -#: gtk/gtkarrow.c:92 gtk/gtkmenu.c:689 gtk/gtkmenuitem.c:363 +#: gtk/gtkarrow.c:92 gtk/gtkmenu.c:711 gtk/gtkmenuitem.c:368 msgid "Arrow Scaling" msgstr "কাঁড়ৰ Scaling" @@ -646,43 +674,43 @@ msgstr "পৃষ্ঠা সম্পূৰ্ণ" msgid "Whether all required fields on the page have been filled out" msgstr "পৃষ্ঠাৰ প্ৰয়োজনীয় অংশসমূহ পূৰ্ণ কৰা হ'ল নে নাই" -#: gtk/gtkbbox.c:99 +#: gtk/gtkbbox.c:101 msgid "Minimum child width" msgstr "চাইল্ডৰ সৰ্বনিম্ন প্ৰস্থ" -#: gtk/gtkbbox.c:100 +#: gtk/gtkbbox.c:102 msgid "Minimum width of buttons inside the box" msgstr "বক্সৰ ভিতৰৰ বুটামৰ সৰ্বনিম্ন প্ৰস্থ" -#: gtk/gtkbbox.c:108 +#: gtk/gtkbbox.c:110 msgid "Minimum child height" msgstr "চাইল্ডৰ সৰ্বনিম্ন উচ্চতা" -#: gtk/gtkbbox.c:109 +#: gtk/gtkbbox.c:111 msgid "Minimum height of buttons inside the box" msgstr "বক্সৰ ভিতৰৰ বুটামৰ সৰ্বনিম্ন উচ্চতা" -#: gtk/gtkbbox.c:117 +#: gtk/gtkbbox.c:119 msgid "Child internal width padding" msgstr "প্ৰস্থ" -#: gtk/gtkbbox.c:118 +#: gtk/gtkbbox.c:120 msgid "Amount to increase child's size on either side" msgstr "চাইল্ডৰ আকাৰ দুয়ো দিশে যি পৰিমাণে বৃদ্ধি কৰা হ'ব" -#: gtk/gtkbbox.c:126 +#: gtk/gtkbbox.c:128 msgid "Child internal height padding" msgstr "চাইল্ডৰ অভ্যন্তৰীণ উচ্চতাৰ পেডিং (Padding)" -#: gtk/gtkbbox.c:127 +#: gtk/gtkbbox.c:129 msgid "Amount to increase child's size on the top and bottom" msgstr "চাইল্ডৰ আকাৰ ওপৰে তলে যি পৰিমাণে বৃদ্ধি কৰা হ'ব" -#: gtk/gtkbbox.c:135 +#: gtk/gtkbbox.c:137 msgid "Layout style" msgstr "পৰিকল্পনাৰ ধৰন" -#: gtk/gtkbbox.c:136 +#: gtk/gtkbbox.c:138 msgid "" "How to layout the buttons in the box. Possible values are default, spread, " "edge, start and end" @@ -690,11 +718,11 @@ msgstr "" "বুটামসমূহক যি ধৰণে বক্সত স্থাপন কৰা হ'ব । সাম্ভাব্য মানসমূহ হ'ল অবিকল্পিত, বিয়পি " "যোৱা, প্ৰান্ত, প্ৰথম আৰু শেষ" -#: gtk/gtkbbox.c:144 +#: gtk/gtkbbox.c:146 msgid "Secondary" msgstr "দ্বিতীয়" -#: gtk/gtkbbox.c:145 +#: gtk/gtkbbox.c:147 msgid "" "If TRUE, the child appears in a secondary group of children, suitable for, e." "g., help buttons" @@ -702,8 +730,8 @@ msgstr "" "TRUE হ'লে, তেন্তে চাইল্ডক এটা দ্বিতীয় চিলড্ৰেন গোটত দেখা যায়; ই সহায়িকা " "প্ৰদৰ্শনকাৰী বুটামৰ বাবে বিশেষ উপযোগী" -#: gtk/gtkbox.c:130 gtk/gtkexpander.c:219 gtk/gtkiconview.c:664 -#: gtk/gtktreeviewcolumn.c:216 +#: gtk/gtkbox.c:130 gtk/gtkexpander.c:219 gtk/gtkiconview.c:665 +#: gtk/gtktreeviewcolumn.c:217 msgid "Spacing" msgstr "মধ্যৱৰ্তী স্থান" @@ -721,7 +749,7 @@ msgid "Whether the children should all be the same size" msgstr "সকলো চিলড্ৰেনৰ আকৃতি সমান হ'ব নে নাই" #: gtk/gtkbox.c:148 gtk/gtkpreview.c:101 gtk/gtktoolbar.c:565 -#: gtk/gtktreeviewcolumn.c:272 +#: gtk/gtktreeviewcolumn.c:273 msgid "Expand" msgstr "প্ৰসাৰণ" @@ -758,7 +786,7 @@ msgid "" "A GtkPackType indicating whether the child is packed with reference to the " "start or end of the parent" msgstr "" -"এটা GtkPackType যি নিৰ্দেশ কৰে যে চাইল্ড পেৰেন্টৰ আৰম্ভ নে শেষৰ সাপেক্ষে স্থাপিত" +"এটা GtkPackType যি নিৰ্দেশ কৰি যে চাইল্ড পেৰেন্টৰ আৰম্ভ নে শেষৰ সাপেক্ষে স্থাপিত" #: gtk/gtkbox.c:176 gtk/gtknotebook.c:694 gtk/gtkpaned.c:241 #: gtk/gtkruler.c:148 @@ -783,13 +811,13 @@ msgid "" "widget" msgstr "যদি বুটামত কোনো লেবেল উইজেট থাকে, তেন্তে এই উইজেটৰ লিখিত শব্দ" -#: gtk/gtkbutton.c:227 gtk/gtkexpander.c:203 gtk/gtklabel.c:516 -#: gtk/gtkmenuitem.c:315 gtk/gtktoolbutton.c:209 +#: gtk/gtkbutton.c:227 gtk/gtkexpander.c:203 gtk/gtklabel.c:517 +#: gtk/gtkmenuitem.c:320 gtk/gtktoolbutton.c:209 msgid "Use underline" msgstr "নিম্নৰেখাঙ্কন কৰক" -#: gtk/gtkbutton.c:228 gtk/gtkexpander.c:204 gtk/gtklabel.c:517 -#: gtk/gtkmenuitem.c:316 +#: gtk/gtkbutton.c:228 gtk/gtkexpander.c:204 gtk/gtklabel.c:518 +#: gtk/gtkmenuitem.c:321 msgid "" "If set, an underline in the text indicates the next character should be used " "for the mnemonic accelerator key" @@ -807,7 +835,7 @@ msgid "" msgstr "" "নিৰ্ধাৰিত থাকিলে, প্ৰদৰ্শনৰ বিকল্পে লেবেলক এটা স্টকৰ বস্তু নিৰ্ব্বাচন কৰিবলৈ ব্যৱহৃত হয়" -#: gtk/gtkbutton.c:243 gtk/gtkcombobox.c:789 gtk/gtkfilechooserbutton.c:393 +#: gtk/gtkbutton.c:243 gtk/gtkcombobox.c:791 gtk/gtkfilechooserbutton.c:393 msgid "Focus on click" msgstr "ক্লিক কৰিলে ফ'কাচ হ'ব" @@ -893,9 +921,9 @@ msgid "" "Whether the child_displacement_x/_y properties should also affect the focus " "rectangle" msgstr "" -"child_displacement_x/_y বৈশিষ্ট্য ফোকাসকাৰী আয়তক্ষেত্ৰকেও প্ৰভাবিত কৰবে নে নাই" +"child_displacement_x/_y বৈশিষ্ট্য ফোকাসকাৰী আয়তক্ষেত্ৰকেও প্ৰভাবিত কৰিব নে নাই" -#: gtk/gtkbutton.c:485 gtk/gtkentry.c:658 gtk/gtkentry.c:1682 +#: gtk/gtkbutton.c:485 gtk/gtkentry.c:689 gtk/gtkentry.c:1713 msgid "Inner Border" msgstr "Border" @@ -965,11 +993,11 @@ msgstr "ইয়াৰ মান সত্য (TRUE) হলে, দিনেৰ #: gtk/gtkcalendar.c:513 msgid "No Month Change" -msgstr "মাস পৰিবৰ্তন কৰা যাবে না" +msgstr "মাস পৰিবৰ্তন কৰা যাব না" #: gtk/gtkcalendar.c:514 msgid "If TRUE, the selected month cannot be changed" -msgstr "ইয়াৰ মান সত্য (TRUE) হলে, বাছাইকৃত মাস পৰিবৰ্তন কৰা যাবে না" +msgstr "ইয়াৰ মান সত্য (TRUE) হলে, বাছাইকৃত মাস পৰিবৰ্তন কৰা যাব না" #: gtk/gtkcalendar.c:528 msgid "Show Week Numbers" @@ -1073,7 +1101,7 @@ msgstr "পূৰ্বনিৰ্দিষ্ট উচ্চতা" #: gtk/gtkcellrenderer.c:261 msgid "Is Expander" -msgstr "প্ৰসাৰিত কৰে" +msgstr "প্ৰসাৰিত কৰি" #: gtk/gtkcellrenderer.c:262 msgid "Row has children" @@ -1117,37 +1145,37 @@ msgstr "ছেলৰ পটভূমি সমষ্টি" #: gtk/gtkcellrenderer.c:304 msgid "Whether this tag affects the cell background color" -msgstr "এই ট্যাগটি ছেলৰপটভূমিৰ ৰংকে প্ৰভাবিত কৰে নে নাই" +msgstr "এই ট্যাগটি ছেলৰপটভূমিৰ ৰংকে প্ৰভাবিত কৰি নে নাই" -#: gtk/gtkcellrendereraccel.c:113 +#: gtk/gtkcellrendereraccel.c:114 msgid "Accelerator key" msgstr "কৰ্মবৰ্ধক-কি" -#: gtk/gtkcellrendereraccel.c:114 +#: gtk/gtkcellrendereraccel.c:115 msgid "The keyval of the accelerator" msgstr "সৰ্বমোট" -#: gtk/gtkcellrendereraccel.c:130 +#: gtk/gtkcellrendereraccel.c:131 msgid "Accelerator modifiers" msgstr "গতিবৰ্ধক পৰিবৰ্তনকাৰী" -#: gtk/gtkcellrendereraccel.c:131 +#: gtk/gtkcellrendereraccel.c:132 msgid "The modifier mask of the accelerator" msgstr "সৰ্বমোট" -#: gtk/gtkcellrendereraccel.c:148 +#: gtk/gtkcellrendereraccel.c:149 msgid "Accelerator keycode" msgstr "গতিবৰ্দ্ধকৰ কী-কোড" -#: gtk/gtkcellrendereraccel.c:149 +#: gtk/gtkcellrendereraccel.c:150 msgid "The hardware keycode of the accelerator" msgstr "সৰ্বমোট" -#: gtk/gtkcellrendereraccel.c:168 +#: gtk/gtkcellrendereraccel.c:169 msgid "Accelerator Mode" msgstr "গতিবৰ্ধক মোড" -#: gtk/gtkcellrendereraccel.c:169 +#: gtk/gtkcellrendereraccel.c:170 msgid "The type of accelerators" msgstr "সৰ্বমোট" @@ -1157,7 +1185,7 @@ msgstr "মডেল" #: gtk/gtkcellrenderercombo.c:108 msgid "The model containing the possible values for the combo box" -msgstr "কম্বোবক্সেৰ সম্ভাব্য মান ধাৰনকাৰী মডেল" +msgstr "কম্বোবক্সৰ সম্ভাব্য মান ধাৰনকাৰী মডেল" #: gtk/gtkcellrenderercombo.c:130 gtk/gtkcomboboxentry.c:106 msgid "Text Column" @@ -1165,7 +1193,7 @@ msgstr "টেক্সট স্তম্ভ" #: gtk/gtkcellrenderercombo.c:131 gtk/gtkcomboboxentry.c:107 msgid "A column in the data source model to get the strings from" -msgstr "ডাটা সোৰ্স মডেলেৰ যি স্তম্ভৰ পৰা পঙ্‌ক্তি নেওয়া হ'ব" +msgstr "ডাটা সোৰ্স মডেলৰ যি স্তম্ভৰ পৰা পঙ্‌ক্তি নেওয়া হ'ব" #: gtk/gtkcellrenderercombo.c:148 msgid "Has Entry" @@ -1199,7 +1227,7 @@ msgstr "Pixbuf প্ৰসাৰক বন্ধ আছে" msgid "Pixbuf for closed expander" msgstr "বন্ধ প্ৰসাৰকেৰ বাবে Pixbuf" -#: gtk/gtkcellrendererpixbuf.c:135 gtk/gtkimage.c:172 gtk/gtkstatusicon.c:226 +#: gtk/gtkcellrendererpixbuf.c:135 gtk/gtkimage.c:172 gtk/gtkstatusicon.c:229 msgid "Stock ID" msgstr "স্টক (Stock) আই.ডি. (ID)" @@ -1208,7 +1236,7 @@ msgid "The stock ID of the stock icon to render" msgstr "যি স্টক (Stock) আইকনটিকে আঁকা হ'ব তাৰ স্টক আইডি (ID)" #: gtk/gtkcellrendererpixbuf.c:143 gtk/gtkrecentmanager.c:245 -#: gtk/gtkstatusicon.c:267 +#: gtk/gtkstatusicon.c:270 msgid "Size" msgstr "মাপ" @@ -1222,7 +1250,7 @@ msgstr "বিস্তাৰিত" #: gtk/gtkcellrendererpixbuf.c:154 msgid "Render detail to pass to the theme engine" -msgstr "থিম ইঞ্জিনেৰ নিকট অঙ্কন সম্পৰ্কিত যি বিস্তাৰিত তথ্য প্ৰেৰণ কৰা হ'ব" +msgstr "থিম ইঞ্জিনেৰ নিকট অঙ্কন সম্পৰ্কিত যি বিস্তাৰিত তথ্য প্ৰৰণ কৰা হ'ব" #: gtk/gtkcellrendererpixbuf.c:187 msgid "Follow State" @@ -1241,8 +1269,8 @@ msgid "Value of the progress bar" msgstr "প্ৰ'গ্ৰেছবাৰৰ মান" #: gtk/gtkcellrendererprogress.c:146 gtk/gtkcellrenderertext.c:195 -#: gtk/gtkentry.c:701 gtk/gtkmessagedialog.c:153 gtk/gtkprogressbar.c:184 -#: gtk/gtktextbuffer.c:198 +#: gtk/gtkentry.c:732 gtk/gtkentrybuffer.c:353 gtk/gtkmessagedialog.c:153 +#: gtk/gtkprogressbar.c:184 gtk/gtktextbuffer.c:198 msgid "Text" msgstr "লিপি" @@ -1281,14 +1309,14 @@ msgid "The vertical text alignment, from 0 (top) to 1 (bottom)." msgstr "উলম্ব অ্যালাইনমেন্ট, ০ (ওপৰত) ৰ পৰা ১ (তল)" #: gtk/gtkcellrendererprogress.c:221 gtk/gtkiconview.c:729 -#: gtk/gtkorientable.c:74 gtk/gtkprogressbar.c:126 gtk/gtkstatusicon.c:325 +#: gtk/gtkorientable.c:74 gtk/gtkprogressbar.c:126 gtk/gtkstatusicon.c:328 #: gtk/gtktrayicon-x11.c:110 msgid "Orientation" msgstr "দিশ" #: gtk/gtkcellrendererprogress.c:222 gtk/gtkprogressbar.c:127 msgid "Orientation and growth direction of the progress bar" -msgstr "প্ৰগ্ৰেছ বাৰেৰ প্ৰাথমিক অবস্থান আৰু বৃদ্ধি পাওয়াৰ দিক" +msgstr "প্ৰগ্ৰেছ বাৰৰ প্ৰাথমিক অবস্থান আৰু বৃদ্ধি পাওয়াৰ দিক" #: gtk/gtkcellrendererspin.c:93 gtk/gtkprogressbar.c:118 gtk/gtkrange.c:367 #: gtk/gtkscalebutton.c:225 gtk/gtkspinbutton.c:208 @@ -1328,13 +1356,13 @@ msgstr "মাৰ্কআপ" msgid "Marked up text to render" msgstr "প্ৰদৰ্শন কৰাৰ বাবে মাৰ্কআপ কৰা টেক্সট" -#: gtk/gtkcellrenderertext.c:211 gtk/gtklabel.c:502 +#: gtk/gtkcellrenderertext.c:211 gtk/gtklabel.c:503 msgid "Attributes" msgstr "বৈশিষ্ট্যাবলী" #: gtk/gtkcellrenderertext.c:212 msgid "A list of style attributes to apply to the text of the renderer" -msgstr "ৰেন্ডাৰাৰেৰ টেক্সটে প্ৰয়োগ কৰাৰ বাবে বিভিন্ন ধাঁচ সম্বলিত এটা তালিকা" +msgstr "ৰেন্ডাৰাৰৰ টেক্সটে প্ৰয়োগ কৰাৰ বাবে বিভিন্ন ধাঁচ সম্বলিত এটা তালিকা" #: gtk/gtkcellrenderertext.c:219 msgid "Single Paragraph Mode" @@ -1342,7 +1370,7 @@ msgstr "একক পেৰাগ্ৰাফ মোড" #: gtk/gtkcellrenderertext.c:220 msgid "Whether or not to keep all text in a single paragraph" -msgstr "সকল টেক্সটকে এটা পেৰাগ্ৰাফে ৰাখিব নে নাই" +msgstr "সকল টেক্সটক এটা পেৰাগ্ৰাফে ৰাখিব নে নাই" #: gtk/gtkcellrenderertext.c:228 gtk/gtkcellview.c:160 gtk/gtktexttag.c:183 msgid "Background color name" @@ -1376,12 +1404,12 @@ msgstr "পুৰোভূমিৰ ৰং" msgid "Foreground color as a GdkColor" msgstr "GdkColor হিচাপে পুৰোভূমিৰ ৰং" -#: gtk/gtkcellrenderertext.c:261 gtk/gtkentry.c:625 gtk/gtktexttag.c:251 -#: gtk/gtktextview.c:573 +#: gtk/gtkcellrenderertext.c:261 gtk/gtkentry.c:656 gtk/gtktexttag.c:251 +#: gtk/gtktextview.c:574 msgid "Editable" msgstr "সম্পাদনযোগ্য" -#: gtk/gtkcellrenderertext.c:262 gtk/gtktexttag.c:252 gtk/gtktextview.c:574 +#: gtk/gtkcellrenderertext.c:262 gtk/gtktexttag.c:252 gtk/gtktextview.c:575 msgid "Whether the text can be modified by the user" msgstr "ব্যৱহাৰকাৰি এই টেক্সকে বদলাতে পাৰবেন নে নাই" @@ -1485,7 +1513,7 @@ msgstr "" "এই ভাষাটিৰ আই.এস.ও. কোড। টেক্সট আঁকাৰ সময় পেনগো এই কোডটিকে ইঙ্গিত হিচাপে ব্যৱহাৰ " "কৰতে পাৰে। যদি আপনি এই ব্যাপাৰটি বুঝতে না পাৰেন তেন্তে আপনাৰ এটিৰ প্ৰয়োজন নেই" -#: gtk/gtkcellrenderertext.c:411 gtk/gtklabel.c:627 gtk/gtkprogressbar.c:206 +#: gtk/gtkcellrenderertext.c:411 gtk/gtklabel.c:628 gtk/gtkprogressbar.c:206 msgid "Ellipsize" msgstr "উপবৃত্তকৰণ" @@ -1498,13 +1526,13 @@ msgstr "" "have enough room to display the entire string" #: gtk/gtkcellrenderertext.c:431 gtk/gtkfilechooserbutton.c:421 -#: gtk/gtklabel.c:647 +#: gtk/gtklabel.c:648 msgid "Width In Characters" msgstr "অক্ষৰ হিচাপে প্ৰস্থ" -#: gtk/gtkcellrenderertext.c:432 gtk/gtklabel.c:648 +#: gtk/gtkcellrenderertext.c:432 gtk/gtklabel.c:649 msgid "The desired width of the label, in characters" -msgstr "অক্ষৰ হিচাপে লেবেলেৰ আকাঙ্খিত প্ৰস্থ" +msgstr "অক্ষৰ হিচাপে লেবেলৰ আকাঙ্খিত প্ৰস্থ" #: gtk/gtkcellrenderertext.c:450 gtk/gtktexttag.c:475 msgid "Wrap mode" @@ -1518,15 +1546,15 @@ msgstr "" "সেল ৰেন্ডাৰাৰে সম্পূৰ্ণ পঙ্‌ক্তি প্ৰদৰ্শনেৰ বাবে পৰ্যাপ্ত স্থান না থাকলে, যিভাবে পঙ্‌ক্তিকে " "একাধিক লাইনে ভেঙ্গে প্ৰদৰ্শন কৰা হ'ব" -#: gtk/gtkcellrenderertext.c:470 gtk/gtkcombobox.c:678 +#: gtk/gtkcellrenderertext.c:470 gtk/gtkcombobox.c:680 msgid "Wrap width" msgstr "গুটিয়ে যাওয়াৰ দৈৰ্ঘ্য" #: gtk/gtkcellrenderertext.c:471 msgid "The width at which the text is wrapped" -msgstr "যি দৈৰ্ঘ্য অতিক্ৰমেৰ পৰ টেক্সটকে গুটিয়ে নেওয়া হ'ব" +msgstr "যি দৈৰ্ঘ্য অতিক্ৰমেৰ পৰ টেক্সটক গুটিয়ে নেওয়া হ'ব" -#: gtk/gtkcellrenderertext.c:491 gtk/gtktreeviewcolumn.c:297 +#: gtk/gtkcellrenderertext.c:491 gtk/gtktreeviewcolumn.c:298 msgid "Alignment" msgstr "দিশা" @@ -1540,7 +1568,7 @@ msgstr "পটভূমিৰ সেট" #: gtk/gtkcellrenderertext.c:503 gtk/gtkcellview.c:191 gtk/gtktexttag.c:565 msgid "Whether this tag affects the background color" -msgstr "এই ট্যাগটি পটভূমিৰ ৰঙকে প্ৰভাবিত কৰে নে নাই" +msgstr "এই ট্যাগটি পটভূমিৰ ৰঙকে প্ৰভাবিত কৰি নে নাই" #: gtk/gtkcellrenderertext.c:506 gtk/gtktexttag.c:576 msgid "Foreground set" @@ -1548,7 +1576,7 @@ msgstr "পুৰোভূমিৰ সেট" #: gtk/gtkcellrenderertext.c:507 gtk/gtktexttag.c:577 msgid "Whether this tag affects the foreground color" -msgstr "এই ট্যাগটি পুৰোভূমিৰ ৰঙকে প্ৰভাবিত কৰে নে নাই" +msgstr "এই ট্যাগটি পুৰোভূমিৰ ৰঙকে প্ৰভাবিত কৰি নে নাই" #: gtk/gtkcellrenderertext.c:510 gtk/gtktexttag.c:584 msgid "Editability set" @@ -1556,7 +1584,7 @@ msgstr "সম্পাদনযোগ্য সেট" #: gtk/gtkcellrenderertext.c:511 gtk/gtktexttag.c:585 msgid "Whether this tag affects text editability" -msgstr "এই ট্যাগটি টেক্সটৰ সম্পাদনযোগ্যতা প্ৰভাবিত কৰে নে নাই" +msgstr "এই ট্যাগটি টেক্সটৰ সম্পাদনযোগ্যতা প্ৰভাবিত কৰি নে নাই" #: gtk/gtkcellrenderertext.c:514 gtk/gtktexttag.c:588 msgid "Font family set" @@ -1564,7 +1592,7 @@ msgstr "বিভিন্ন ফন্ট বৰ্গেৰ সমষ্টি #: gtk/gtkcellrenderertext.c:515 gtk/gtktexttag.c:589 msgid "Whether this tag affects the font family" -msgstr "এই ট্যাগ (tag) ফন্ট বৰ্গকে প্ৰভাবিত কৰে নে নাই" +msgstr "এই ট্যাগ (tag) ফন্ট বৰ্গকে প্ৰভাবিত কৰি নে নাই" #: gtk/gtkcellrenderertext.c:518 gtk/gtktexttag.c:592 msgid "Font style set" @@ -1572,7 +1600,7 @@ msgstr "ফন্ট কায়দাৰ (ধৰন) সমষ্টি" #: gtk/gtkcellrenderertext.c:519 gtk/gtktexttag.c:593 msgid "Whether this tag affects the font style" -msgstr "এই ট্যাগ (tag) ফন্ট কায়দাকে (ধৰনকে) প্ৰভাবিত কৰে নে নাই" +msgstr "এই ট্যাগ (tag) ফন্ট কায়দাকে (ধৰনকে) প্ৰভাবিত কৰি নে নাই" #: gtk/gtkcellrenderertext.c:522 gtk/gtktexttag.c:596 msgid "Font variant set" @@ -1580,7 +1608,7 @@ msgstr "ফন্ট ৰূপভেদেৰ সেট" #: gtk/gtkcellrenderertext.c:523 gtk/gtktexttag.c:597 msgid "Whether this tag affects the font variant" -msgstr "এই ট্যাগ (tag) ফন্ট ৰূপভেদকে প্ৰভাবিত কৰে নে নাই" +msgstr "এই ট্যাগ (tag) ফন্ট ৰূপভেদকে প্ৰভাবিত কৰি নে নাই" #: gtk/gtkcellrenderertext.c:526 gtk/gtktexttag.c:600 msgid "Font weight set" @@ -1588,7 +1616,7 @@ msgstr "বিভিন্ন ফন্ট আকৃতিৰ (Weight) সমষ #: gtk/gtkcellrenderertext.c:527 gtk/gtktexttag.c:601 msgid "Whether this tag affects the font weight" -msgstr "এই ট্যাগ (tag) ফন্ট আকৃতিকে (Weight) প্ৰভাবিত কৰে নে নাই" +msgstr "এই ট্যাগ (tag) ফন্ট আকৃতিকে (Weight) প্ৰভাবিত কৰি নে নাই" #: gtk/gtkcellrenderertext.c:530 gtk/gtktexttag.c:604 msgid "Font stretch set" @@ -1596,15 +1624,15 @@ msgstr "ফন্ট প্ৰসাৰণ সমষ্টি" #: gtk/gtkcellrenderertext.c:531 gtk/gtktexttag.c:605 msgid "Whether this tag affects the font stretch" -msgstr "এই ট্যাগ (tag) ফন্ট প্ৰসাৰণ প্ৰভাবিত কৰে নে নাই" +msgstr "এই ট্যাগ (tag) ফন্ট প্ৰসাৰণ প্ৰভাবিত কৰি নে নাই" #: gtk/gtkcellrenderertext.c:534 gtk/gtktexttag.c:608 msgid "Font size set" -msgstr "ফন্ট আকাৰেৰ সমষ্টি" +msgstr "ফন্ট আকাৰৰ সমষ্টি" #: gtk/gtkcellrenderertext.c:535 gtk/gtktexttag.c:609 msgid "Whether this tag affects the font size" -msgstr "এই ট্যাগ (tag) ফন্ট আকাৰকে প্ৰভাবিত কৰে নে নাই" +msgstr "এই ট্যাগ (tag) ফন্ট আকাৰকে প্ৰভাবিত কৰি নে নাই" #: gtk/gtkcellrenderertext.c:538 gtk/gtktexttag.c:612 msgid "Font scale set" @@ -1612,7 +1640,7 @@ msgstr "ফন্ট স্কেল সেট" #: gtk/gtkcellrenderertext.c:539 gtk/gtktexttag.c:613 msgid "Whether this tag scales the font size by a factor" -msgstr "এই ট্যাগটি ফন্টৰ আকাৰকে কয়েক গুণ পৰিবৰ্তন কৰে নে নাই" +msgstr "এই ট্যাগটি ফন্টৰ আকাৰকে কয়েক গুণ পৰিবৰ্তন কৰি নে নাই" #: gtk/gtkcellrenderertext.c:542 gtk/gtktexttag.c:632 msgid "Rise set" @@ -1620,7 +1648,7 @@ msgstr "উত্থিত" #: gtk/gtkcellrenderertext.c:543 gtk/gtktexttag.c:633 msgid "Whether this tag affects the rise" -msgstr "এটি উত্থান (Rise) প্ৰভাবিত কৰে নে নাই" +msgstr "এটি উত্থান (Rise) প্ৰভাবিত কৰি নে নাই" #: gtk/gtkcellrenderertext.c:546 gtk/gtktexttag.c:648 msgid "Strikethrough set" @@ -1628,7 +1656,7 @@ msgstr "মাঝ বৰাবৰ ৰেখাংকন কৰা সেট" #: gtk/gtkcellrenderertext.c:547 gtk/gtktexttag.c:649 msgid "Whether this tag affects strikethrough" -msgstr "এই ট্যাগ (tag) মাঝ বৰাবৰ ৰেখাংকন কৰা অবস্থাকে প্ৰভাবিত কৰে নে নাই" +msgstr "এই ট্যাগ (tag) মাঝ বৰাবৰ ৰেখাংকন কৰা অবস্থাকে প্ৰভাবিত কৰি নে নাই" #: gtk/gtkcellrenderertext.c:550 gtk/gtktexttag.c:656 msgid "Underline set" @@ -1636,7 +1664,7 @@ msgstr "তল বৰাবৰ ৰেখাংকন কৰা সমষ্ট #: gtk/gtkcellrenderertext.c:551 gtk/gtktexttag.c:657 msgid "Whether this tag affects underlining" -msgstr "এই ট্যাগ (tag) তল বৰাবৰ ৰেখাংকন কৰাকে প্ৰভাবিত কৰে নে নাই" +msgstr "এই ট্যাগ (tag) তল বৰাবৰ ৰেখাংকন কৰাকে প্ৰভাবিত কৰি নে নাই" #: gtk/gtkcellrenderertext.c:554 gtk/gtktexttag.c:620 msgid "Language set" @@ -1644,7 +1672,7 @@ msgstr "ভাষা সমষ্টি" #: gtk/gtkcellrenderertext.c:555 gtk/gtktexttag.c:621 msgid "Whether this tag affects the language the text is rendered as" -msgstr "যি ভাষায় টেক্সট লেখা হচ্ছে, এই ট্যাগটি তাকে প্ৰভাবিত কৰে নে নাই" +msgstr "যি ভাষায় টেক্সট লেখা হচ্ছে, এই ট্যাগটি তাকে প্ৰভাবিত কৰি নে নাই" #: gtk/gtkcellrenderertext.c:558 msgid "Ellipsize set" @@ -1652,7 +1680,7 @@ msgstr "উপবৃত্তকৃত সেট" #: gtk/gtkcellrenderertext.c:559 msgid "Whether this tag affects the ellipsize mode" -msgstr "এই ট্যাগটি উপবৃত্তকৃত মোডকে প্ৰভাবিত কৰে নে নাই" +msgstr "এই ট্যাগটি উপবৃত্তকৃত মোডকে প্ৰভাবিত কৰি নে নাই" #: gtk/gtkcellrenderertext.c:562 msgid "Align set" @@ -1724,7 +1752,7 @@ msgstr "নিৰ্ধাৰক স্থান" msgid "Spacing around check or radio indicator" msgstr "টিক বা ৰেডিও নিৰ্দেশকে ব্যৱহৃত স্পেস" -#: gtk/gtkcheckmenuitem.c:98 gtk/gtkmenu.c:500 gtk/gtktoggleaction.c:119 +#: gtk/gtkcheckmenuitem.c:98 gtk/gtkmenu.c:501 gtk/gtktoggleaction.c:119 #: gtk/gtktogglebutton.c:115 gtk/gtktoggletoolbutton.c:114 msgid "Active" msgstr "সক্ৰিয়" @@ -1758,7 +1786,8 @@ msgid "Whether or not to give the color an alpha value" msgstr "ৰংটিকে এটা আলফা মান দিয়া হ'ব নে নাই" #: gtk/gtkcolorbutton.c:186 gtk/gtkfilechooserbutton.c:407 -#: gtk/gtkfontbutton.c:142 gtk/gtkprintjob.c:116 gtk/gtktreeviewcolumn.c:264 +#: gtk/gtkfontbutton.c:142 gtk/gtkprintjob.c:116 gtk/gtkstatusicon.c:424 +#: gtk/gtktreeviewcolumn.c:265 msgid "Title" msgstr "শিৰোনাম" @@ -1789,7 +1818,7 @@ msgstr "ওপাসিটি (অস্বচ্ছতা) নিয়ন্ত #: gtk/gtkcolorsel.c:280 msgid "Whether the color selector should allow setting opacity" -msgstr "ৰং নিৰ্বাচকৰ পৰা ওপাসিটি (অস্বচ্ছতা) নিৰ্ধাৰণ কৰা যাবে নে নাই" +msgstr "ৰং নিৰ্বাচকৰ পৰা ওপাসিটি (অস্বচ্ছতা) নিৰ্ধাৰণ কৰা যাব নে নাই" #: gtk/gtkcolorsel.c:286 msgid "Has palette" @@ -1819,7 +1848,7 @@ msgstr "ৰং নিৰ্বাচকে যি পেলেট ব্যৱ # #: gtk/gtkcolorseldialog.c:102 msgid "Color Selection" -msgstr "রং নির্বাচন" +msgstr "ৰং নিৰ্বাচন" # #: gtk/gtkcolorseldialog.c:103 @@ -1875,7 +1904,7 @@ msgstr "বাতিল বৈশিষ্ট্য, অগ্ৰাহ্য #: gtk/gtkcombo.c:159 msgid "Case sensitive" -msgstr "বড় বা ছোট হাতেৰ অক্ষৰ পৃথকভাবে বিবেচনা কৰে" +msgstr "বড় বা ছোট হাতেৰ অক্ষৰ পৃথকভাবে বিবেচনা কৰি" #: gtk/gtkcombo.c:160 msgid "Whether list item matching is case sensitive" @@ -1889,7 +1918,7 @@ msgstr "ৰিক্ত অনুমোদন কৰো" #: gtk/gtkcombo.c:168 msgid "Whether an empty value may be entered in this field" -msgstr "এই ক্ষেত্ৰে (Field) কোন ৰিক্ত মান লেখা যাবে নে নাই" +msgstr "এই ক্ষেত্ৰে (Field) কোন ৰিক্ত মান লেখা যাব নে নাই" #: gtk/gtkcombo.c:175 msgid "Value in list" @@ -1899,112 +1928,112 @@ msgstr "মানটি তালিকায় আছে" msgid "Whether entered values must already be present in the list" msgstr "যিসব মান লেখা হ'ব সেগুলো সৰ্বদা তালিকায় থাকতে হ'ব নে নাই" -#: gtk/gtkcombobox.c:661 +#: gtk/gtkcombobox.c:663 msgid "ComboBox model" msgstr "কম্বোবক্স মডেল" -#: gtk/gtkcombobox.c:662 +#: gtk/gtkcombobox.c:664 msgid "The model for the combo box" -msgstr "কম্বোবক্সেৰ মডেল" +msgstr "কম্বোবক্সৰ মডেল" -#: gtk/gtkcombobox.c:679 +#: gtk/gtkcombobox.c:681 msgid "Wrap width for laying out the items in a grid" msgstr "গুটানো প্ৰস্থ উল্লিখিত সময় অবধি" -#: gtk/gtkcombobox.c:701 +#: gtk/gtkcombobox.c:703 msgid "Row span column" msgstr "প্ৰতি শাৰীতে স্তম্ভেৰ সংখ্যা" -#: gtk/gtkcombobox.c:702 +#: gtk/gtkcombobox.c:704 msgid "TreeModel column containing the row span values" msgstr "শাৰীৰ প্ৰস্থেৰ মান ধাৰনকাৰী TreeModel স্তম্ভ" -#: gtk/gtkcombobox.c:723 +#: gtk/gtkcombobox.c:725 msgid "Column span column" msgstr "প্ৰতি স্তম্ভে স্তম্ভেৰ সংখ্যা" -#: gtk/gtkcombobox.c:724 +#: gtk/gtkcombobox.c:726 msgid "TreeModel column containing the column span values" msgstr "স্তম্ভেৰ প্ৰস্থেৰ মান ধাৰনকাৰী TreeModel স্তম্ভ" -#: gtk/gtkcombobox.c:745 +#: gtk/gtkcombobox.c:747 msgid "Active item" msgstr "সক্ৰিয় আইটেম" -#: gtk/gtkcombobox.c:746 +#: gtk/gtkcombobox.c:748 msgid "The item which is currently active" msgstr "বৰ্তমানে সক্ৰিয় আইটেম" -#: gtk/gtkcombobox.c:765 gtk/gtkuimanager.c:222 +#: gtk/gtkcombobox.c:767 gtk/gtkuimanager.c:222 msgid "Add tearoffs to menus" msgstr "মেনুতে টিয়াৰঅফ (Tearoff) যোগ কৰো" -#: gtk/gtkcombobox.c:766 +#: gtk/gtkcombobox.c:768 msgid "Whether dropdowns should have a tearoff menu item" msgstr "ড্ৰপডাউনে কোন টিয়াৰ-অফ তালিকা বস্তু থাকবে নে নাই" -#: gtk/gtkcombobox.c:781 gtk/gtkentry.c:650 +#: gtk/gtkcombobox.c:783 gtk/gtkentry.c:681 msgid "Has Frame" msgstr "ফ্ৰেম আছে" -#: gtk/gtkcombobox.c:782 +#: gtk/gtkcombobox.c:784 msgid "Whether the combo box draws a frame around the child" msgstr "চাইল্ডৰ চাৰদিকে কম্বো বাক্স কোন ফ্ৰেম আঁকবে নে নাই" -#: gtk/gtkcombobox.c:790 +#: gtk/gtkcombobox.c:792 msgid "Whether the combo box grabs focus when it is clicked with the mouse" -msgstr "মাউসেৰ সাহায্যি কম্বো বাক্সকে ক্লিক কৰা হলে তা ফ'কাচ হয়ে যাবে নে নাই" +msgstr "মাউছৰ সহায়ত কম্বো বাক্সকে ক্লিক কৰা হলে তা ফ'কাচ হয়ে যাব নে নাই" -#: gtk/gtkcombobox.c:805 gtk/gtkmenu.c:555 +#: gtk/gtkcombobox.c:807 gtk/gtkmenu.c:556 msgid "Tearoff Title" msgstr "বিচ্ছিন্ন শিৰোনাম" -#: gtk/gtkcombobox.c:806 +#: gtk/gtkcombobox.c:808 msgid "" "A title that may be displayed by the window manager when the popup is torn-" "off" msgstr "প'পআপ হলো" -#: gtk/gtkcombobox.c:823 +#: gtk/gtkcombobox.c:825 msgid "Popup shown" msgstr "পপ-আপ" -#: gtk/gtkcombobox.c:824 +#: gtk/gtkcombobox.c:826 msgid "Whether the combo's dropdown is shown" msgstr "হলো" -#: gtk/gtkcombobox.c:840 +#: gtk/gtkcombobox.c:842 msgid "Button Sensitivity" msgstr "Button Sensitivity" # -#: gtk/gtkcombobox.c:841 +#: gtk/gtkcombobox.c:843 msgid "Whether the dropdown button is sensitive when the model is empty" -msgstr "কোন বুটামৰ মাউসেৰ সাহায্যি ক্লিক কৰা হলে তা ফ'কাচ হয়ে যাবে নে নাই" +msgstr "কোন বুটামৰ মাউছৰ সহায়ত ক্লিক কৰা হলে তা ফ'কাচ হয়ে যাব নে নাই" -#: gtk/gtkcombobox.c:848 +#: gtk/gtkcombobox.c:850 msgid "Appears as list" msgstr "তালিকাৰ মত মনে হয়" -#: gtk/gtkcombobox.c:849 +#: gtk/gtkcombobox.c:851 msgid "Whether dropdowns should look like lists rather than menus" msgstr "ড্ৰপডাউনেৰ চেহাৰা তালিকাৰ মত নহ'বকি মেনুৰ মত" -#: gtk/gtkcombobox.c:865 +#: gtk/gtkcombobox.c:867 msgid "Arrow Size" msgstr "মাপ" -#: gtk/gtkcombobox.c:866 +#: gtk/gtkcombobox.c:868 msgid "The minimum size of the arrow in the combo box" msgstr "সৰ্বমোট" -#: gtk/gtkcombobox.c:881 gtk/gtkentry.c:750 gtk/gtkhandlebox.c:174 +#: gtk/gtkcombobox.c:883 gtk/gtkentry.c:781 gtk/gtkhandlebox.c:174 #: gtk/gtkmenubar.c:194 gtk/gtkstatusbar.c:186 gtk/gtktoolbar.c:623 #: gtk/gtkviewport.c:122 msgid "Shadow type" msgstr "ছায়াৰ ধৰন" -#: gtk/gtkcombobox.c:882 +#: gtk/gtkcombobox.c:884 msgid "Which kind of shadow to draw around the combo box" msgstr "সৰ্বমোট" @@ -2018,11 +2047,11 @@ msgstr "আকাৰ পৰিবৰ্তনেৰ ইভেন্টকে য #: gtk/gtkcontainer.c:246 msgid "Border width" -msgstr "প্ৰান্তেৰ প্ৰস্থ" +msgstr "প্ৰান্তৰ প্ৰস্থ" #: gtk/gtkcontainer.c:247 msgid "The width of the empty border outside the containers children" -msgstr "কনটেইনাৰ চিলড্ৰানেৰ বাইৰেৰ ৰিক্ত প্ৰান্তেৰ প্ৰস্থ" +msgstr "কনটেইনাৰ চিলড্ৰানেৰ বাইৰৰ ৰিক্ত প্ৰান্তৰ প্ৰস্থ" #: gtk/gtkcontainer.c:255 msgid "Child" @@ -2030,7 +2059,7 @@ msgstr "চাইল্ড" #: gtk/gtkcontainer.c:256 msgid "Can be used to add a new child to the container" -msgstr "কনটেইনাৰে এটা নতুন চাইল্ড যোগ কৰতে ব্যৱহাৰ কৰা যাবে" +msgstr "কনটেইনাৰে এটা নতুন চাইল্ড যোগ কৰতে ব্যৱহাৰ কৰা যাব" #: gtk/gtkcurve.c:124 msgid "Curve type" @@ -2046,7 +2075,7 @@ msgstr "সৰ্বনিম্ন এক্স অক্ষ" #: gtk/gtkcurve.c:133 msgid "Minimum possible value for X" -msgstr "এক্সেৰ সম্ভাব্য সৰ্বনিম্ন মান" +msgstr "এক্সৰ সম্ভাব্য সৰ্বনিম্ন মান" #: gtk/gtkcurve.c:141 msgid "Maximum X" @@ -2054,7 +2083,7 @@ msgstr "এক্স ইয়াৰ সৰ্বোচ্চ মান" #: gtk/gtkcurve.c:142 msgid "Maximum possible X value" -msgstr "এক্সেৰ সম্ভাব্য সৰ্বোচ্চ মান" +msgstr "এক্সৰ সম্ভাব্য সৰ্বোচ্চ মান" #: gtk/gtkcurve.c:150 msgid "Minimum Y" @@ -2080,74 +2109,82 @@ msgstr "বিভাজক আছে" msgid "The dialog has a separator bar above its buttons" msgstr "ডায়ালগটিতে Bঅতনেৰ ওপৰ এটা বিভাজক আছে" -#: gtk/gtkdialog.c:191 +#: gtk/gtkdialog.c:191 gtk/gtkinfobar.c:439 msgid "Content area border" -msgstr "বস্তু ক্ষেত্ৰেৰ প্ৰান্ত" +msgstr "বস্তু ক্ষেত্ৰৰ প্ৰান্ত" #: gtk/gtkdialog.c:192 msgid "Width of border around the main dialog area" -msgstr "মূল ডায়ালগ ক্ষেত্ৰেৰ চাৰপাশেৰ প্ৰান্তেৰ প্ৰস্থ" +msgstr "মূল ডায়ালগ ক্ষেত্ৰৰ চাৰপাশৰ প্ৰান্তৰ প্ৰস্থ" # -#: gtk/gtkdialog.c:209 +#: gtk/gtkdialog.c:209 gtk/gtkinfobar.c:456 msgid "Content area spacing" msgstr "বিসয়বস্তুৰ পেডিং" # #: gtk/gtkdialog.c:210 msgid "Spacing between elements of the main dialog area" -msgstr "মানসূচক টেক্সট আৰু স্লাইডাৰ/থ্ৰু অংশেৰ মধ্যবৰ্তী স্থান তৰ সংখ্যা" +msgstr "মানসূচক টেক্সট আৰু স্লাইডাৰ/থ্ৰু অংশৰ মধ্যবৰ্তী স্থান তৰ সংখ্যা" -#: gtk/gtkdialog.c:217 +#: gtk/gtkdialog.c:217 gtk/gtkinfobar.c:472 msgid "Button spacing" msgstr "বুটামৰ বাবে স্থান ইয়াৰ সংখ্যা" -#: gtk/gtkdialog.c:218 +#: gtk/gtkdialog.c:218 gtk/gtkinfobar.c:473 msgid "Spacing between buttons" msgstr "দুটি বুটামৰ মাজত স্থান ইয়াৰ সংখ্যা" -#: gtk/gtkdialog.c:226 +#: gtk/gtkdialog.c:226 gtk/gtkinfobar.c:488 msgid "Action area border" -msgstr "কৰ্মক্ষেত্ৰেৰ (Action area) প্ৰান্ত" +msgstr "কৰ্মক্ষেত্ৰৰ (Action area) প্ৰান্ত" #: gtk/gtkdialog.c:227 msgid "Width of border around the button area at the bottom of the dialog" -msgstr "ডায়ালগেৰ তলৰ দিকে অবস্থিত বুটামৰ চাৰপাশেৰ প্ৰস্থ" +msgstr "ডায়ালগেৰ তলৰ দিকে অবস্থিত বুটামৰ চাৰপাশৰ প্ৰস্থ" -#: gtk/gtkentry.c:605 gtk/gtklabel.c:590 +#: gtk/gtkentry.c:628 +msgid "Text Buffer" +msgstr "টেক্সট বাফাৰ" + +#: gtk/gtkentry.c:629 +msgid "Text buffer object which actually stores entry text" +msgstr "টেকস্ট বাফাৰ অব্জেক্ট যি প্ৰকৃততে নিবেশৰ লিপি ৰক্ষা কৰে" + +#: gtk/gtkentry.c:636 gtk/gtklabel.c:591 msgid "Cursor Position" -msgstr "কাৰ্সাৰেৰ অবস্থান" +msgstr "কাৰ্ছাৰৰ অবস্থান" -#: gtk/gtkentry.c:606 gtk/gtklabel.c:591 +#: gtk/gtkentry.c:637 gtk/gtklabel.c:592 msgid "The current position of the insertion cursor in chars" -msgstr "অক্ষৰ হিচাপে লেখা ভৰোৱাৰ (Insertion) কাৰ্সাৰেৰ অবস্থান" +msgstr "অক্ষৰ হিচাপে লেখা ভৰোৱাৰ (Insertion) কাৰ্ছাৰৰ অবস্থান" -#: gtk/gtkentry.c:615 gtk/gtklabel.c:600 +#: gtk/gtkentry.c:646 gtk/gtklabel.c:601 msgid "Selection Bound" msgstr "চিহ্নিত কৰাৰ সীমানা" -#: gtk/gtkentry.c:616 gtk/gtklabel.c:601 +#: gtk/gtkentry.c:647 gtk/gtklabel.c:602 msgid "" "The position of the opposite end of the selection from the cursor in chars" -msgstr "অক্ষৰ হিচাপে চিহ্নিত অংশেৰ বিপৰীত প্ৰান্তেৰ অবস্থান" +msgstr "অক্ষৰ হিচাপে চিহ্নিত অংশৰ বিপৰীত প্ৰান্তৰ অবস্থান" -#: gtk/gtkentry.c:626 +#: gtk/gtkentry.c:657 msgid "Whether the entry contents can be edited" -msgstr "অন্তৰ্ভুক্তিৰ (Entry) অভ্যন্তৰীণ বস্তু (Content) এডিট কৰা যাবে নে নাই" +msgstr "অন্তৰ্ভুক্তিৰ (Entry) অভ্যন্তৰীণ বস্তু (Content) এডিট কৰা যাব নে নাই" -#: gtk/gtkentry.c:633 +#: gtk/gtkentry.c:664 gtk/gtkentrybuffer.c:383 msgid "Maximum length" msgstr "সৰ্বোচ্চ দৈৰ্ঘ্য" -#: gtk/gtkentry.c:634 +#: gtk/gtkentry.c:665 gtk/gtkentrybuffer.c:384 msgid "Maximum number of characters for this entry. Zero if no maximum" msgstr "এই অন্তৰ্ভুক্তিৰ বাবে সৰ্বোচ্চ সংখ্যক অক্ষৰ। ইয়াৰ মান শূণ্য হতে পাৰবেন না" -#: gtk/gtkentry.c:642 +#: gtk/gtkentry.c:673 msgid "Visibility" msgstr "দৃষ্টিগ্ৰাহ্যতা" -#: gtk/gtkentry.c:643 +#: gtk/gtkentry.c:674 msgid "" "FALSE displays the \"invisible char\" instead of the actual text (password " "mode)" @@ -2155,30 +2192,30 @@ msgstr "" "যদি FALSE হয় তেন্তে প্ৰকৃত টেক্সটৰ পৰিবৰ্তে \"অদৃশ্য অক্ষৰ\" দেখা যায় (পাসওয়াৰ্ডেৰ " "ক্ষেত্ৰে প্ৰযোজ্য)" -#: gtk/gtkentry.c:651 +#: gtk/gtkentry.c:682 msgid "FALSE removes outside bevel from entry" -msgstr "FASLE তালিকাৰ পৰা বহিঃস্থ বেভেলকে অপসাৰণ কৰে" +msgstr "FASLE তালিকাৰ পৰা বহিঃস্থ বেভেলকে অপসাৰণ কৰি" -#: gtk/gtkentry.c:659 +#: gtk/gtkentry.c:690 msgid "" "Border between text and frame. Overrides the inner-border style property" msgstr "Border" -#: gtk/gtkentry.c:666 gtk/gtkentry.c:1232 +#: gtk/gtkentry.c:697 gtk/gtkentry.c:1263 msgid "Invisible character" msgstr "অদৃশ্য অক্ষৰ" -#: gtk/gtkentry.c:667 gtk/gtkentry.c:1233 +#: gtk/gtkentry.c:698 gtk/gtkentry.c:1264 msgid "The character to use when masking entry contents (in \"password mode\")" msgstr "" "অন্তৰ্ভুক্তিৰ (Entry) বিষয়বস্তু আড়াল কৰাৰ বাবে ব্যৱহৃত অক্ষৰ (\"পাসওয়াৰ্ড মোড\" এ " "ব্যৱহৃত)" -#: gtk/gtkentry.c:674 +#: gtk/gtkentry.c:705 msgid "Activates default" -msgstr "অবিকল্পিতকে সক্ৰিয় কৰে" +msgstr "অবিকল্পিতকে সক্ৰিয় কৰি" -#: gtk/gtkentry.c:675 +#: gtk/gtkentry.c:706 msgid "" "Whether to activate the default widget (such as the default button in a " "dialog) when Enter is pressed" @@ -2186,331 +2223,338 @@ msgstr "" "Enter বুটাম চাপলে অবিকল্পিতকে সক্ৰিয় কৰা হ'ব নে নাই (যিমন কোন ডায়ালগেৰ অবিকল্পিত " "বুটাম)" -#: gtk/gtkentry.c:681 +#: gtk/gtkentry.c:712 msgid "Width in chars" -msgstr "অক্ষৰেৰ প্ৰস্থ" +msgstr "অক্ষৰৰ প্ৰস্থ" -#: gtk/gtkentry.c:682 +#: gtk/gtkentry.c:713 msgid "Number of characters to leave space for in the entry" msgstr "প্ৰতি অন্তৰ্ভুক্তিতে যত অক্ষৰ ৰিক্ত ৰাখিব" -#: gtk/gtkentry.c:691 +#: gtk/gtkentry.c:722 msgid "Scroll offset" msgstr "স্ক্ৰল অফসেট" -#: gtk/gtkentry.c:692 +#: gtk/gtkentry.c:723 msgid "Number of pixels of the entry scrolled off the screen to the left" msgstr "অন্তৰ্ভুক্তিৰ (Entry) যি সংখ্যক পিক্সেলকে পৰ্দ্দাৰ বামে সৰিয়ে নিয়ে যাওয়া হৈছে" -#: gtk/gtkentry.c:702 +#: gtk/gtkentry.c:733 msgid "The contents of the entry" msgstr "অন্তৰ্ভুক্তিৰ (Entry) অভ্যন্তৰীণ বস্তু" -#: gtk/gtkentry.c:717 gtk/gtkmisc.c:73 +#: gtk/gtkentry.c:748 gtk/gtkmisc.c:73 msgid "X align" msgstr "এক্স অক্ষ" -#: gtk/gtkentry.c:718 gtk/gtkmisc.c:74 +#: gtk/gtkentry.c:749 gtk/gtkmisc.c:74 msgid "" "The horizontal alignment, from 0 (left) to 1 (right). Reversed for RTL " "layouts." msgstr "পথালি সংৰেখন, ০ (বাম)ৰ পৰা ১ (ডান)। RTL নকশাৰ বাবে বিপৰীত" -#: gtk/gtkentry.c:734 +#: gtk/gtkentry.c:765 msgid "Truncate multiline" msgstr "Truncate multiline" -#: gtk/gtkentry.c:735 +#: gtk/gtkentry.c:766 msgid "Whether to truncate multiline pastes to one line." msgstr "Whether to truncate multiline pastes to one line." -#: gtk/gtkentry.c:751 +#: gtk/gtkentry.c:782 msgid "Which kind of shadow to draw around the entry when has-frame is set" msgstr "সৰ্বমোট হলো" -#: gtk/gtkentry.c:766 gtk/gtktextview.c:653 +#: gtk/gtkentry.c:797 gtk/gtktextview.c:654 msgid "Overwrite mode" msgstr "ওপৰ দিয়ে লেখাৰ মোড" # -#: gtk/gtkentry.c:767 +#: gtk/gtkentry.c:798 msgid "Whether new text overwrites existing text" msgstr "যি টেক্সট লেখা হ'ব তা বিদ্যমান টেক্সটৰ ওপৰ দিয়ে লেখা হ'ব নে নাই" -#: gtk/gtkentry.c:781 +#: gtk/gtkentry.c:812 gtk/gtkentrybuffer.c:368 msgid "Text length" msgstr "টেক্সটৰ দৈৰ্ঘ্য" -#: gtk/gtkentry.c:782 +#: gtk/gtkentry.c:813 msgid "Length of the text currently in the entry" msgstr "Length of the text currently in the entry" # -#: gtk/gtkentry.c:797 +#: gtk/gtkentry.c:828 msgid "Invisible char set" msgstr "অদৃশ্য সেট" # -#: gtk/gtkentry.c:798 +#: gtk/gtkentry.c:829 msgid "Whether the invisible char has been set" msgstr "কামটো দৃশ্যমান নে নাই।" -#: gtk/gtkentry.c:816 +#: gtk/gtkentry.c:847 msgid "Caps Lock warning" msgstr "Caps Lock warning" -#: gtk/gtkentry.c:817 +#: gtk/gtkentry.c:848 msgid "Whether password entries will show a warning when Caps Lock is on" msgstr "Whether password entries will show a warning when Caps Lock is on" # -#: gtk/gtkentry.c:831 +#: gtk/gtkentry.c:862 msgid "Progress Fraction" msgstr "ভগ্নাংশ" # -#: gtk/gtkentry.c:832 +#: gtk/gtkentry.c:863 msgid "The current fraction of the task that's been completed" -msgstr "পুৰো কাজটাৰ যি ভগ্নাংশ সম্পূৰ্ণ হৈছে" +msgstr "পুৰো কামটাৰ যি ভগ্নাংশ সম্পূৰ্ণ হৈছে" # -#: gtk/gtkentry.c:849 +#: gtk/gtkentry.c:880 msgid "Progress Pulse Step" msgstr "স্পন্দন ধাপ" # -#: gtk/gtkentry.c:850 +#: gtk/gtkentry.c:881 msgid "" "The fraction of total entry width to move the progress bouncing block for " "each call to gtk_entry_progress_pulse()" msgstr "" -"মোট কামৰ যি ভগাংশ পৰিমাণ সম্পন্ন হলে স্পন্দনেৰ ফলে লাফাতে থাকা ব্লকটিকে সৰানো " -"যাবে " +"মোট কামৰ যি ভগাংশ পৰিমাণ সম্পন্ন হলে স্পন্দনেৰ ফলে লাফাতে থাকা ব্লকটিকে সৰানো যাব " # -#: gtk/gtkentry.c:866 +#: gtk/gtkentry.c:897 msgid "Primary pixbuf" msgstr "পিক্সবাফ" # -#: gtk/gtkentry.c:867 +#: gtk/gtkentry.c:898 msgid "Primary pixbuf for the entry" msgstr "খোলা প্ৰসাৰকেৰ বাবে Pixbuf" # -#: gtk/gtkentry.c:881 +#: gtk/gtkentry.c:912 msgid "Secondary pixbuf" msgstr "দ্বিতীয় Text" # -#: gtk/gtkentry.c:882 +#: gtk/gtkentry.c:913 msgid "Secondary pixbuf for the entry" msgstr "সম্মুখগামী গৌণ স্টেপাৰ" -#: gtk/gtkentry.c:896 +#: gtk/gtkentry.c:927 msgid "Primary stock ID" msgstr "Primary stock ID" -#: gtk/gtkentry.c:897 +#: gtk/gtkentry.c:928 msgid "Stock ID for primary icon" msgstr "Stock ID for primary icon" # -#: gtk/gtkentry.c:911 +#: gtk/gtkentry.c:942 msgid "Secondary stock ID" msgstr "দ্বিতীয় Text" -#: gtk/gtkentry.c:912 +#: gtk/gtkentry.c:943 msgid "Stock ID for secondary icon" msgstr "Stock ID for secondary icon" # -#: gtk/gtkentry.c:926 +#: gtk/gtkentry.c:957 msgid "Primary icon name" msgstr "তালিকা সৰ্বমোট" -#: gtk/gtkentry.c:927 +#: gtk/gtkentry.c:958 msgid "Icon name for primary icon" msgstr "Icon name for primary icon" # -#: gtk/gtkentry.c:941 +#: gtk/gtkentry.c:972 msgid "Secondary icon name" msgstr "দ্বিতীয় Text" -#: gtk/gtkentry.c:942 +#: gtk/gtkentry.c:973 msgid "Icon name for secondary icon" msgstr "Icon name for secondary icon" -#: gtk/gtkentry.c:956 +#: gtk/gtkentry.c:987 msgid "Primary GIcon" msgstr "Primary GIcon" # -#: gtk/gtkentry.c:957 +#: gtk/gtkentry.c:988 msgid "GIcon for primary icon" msgstr "এই উইন্ডোৰ বাবে আইকন" # -#: gtk/gtkentry.c:971 +#: gtk/gtkentry.c:1002 msgid "Secondary GIcon" msgstr "দ্বিতীয়" -#: gtk/gtkentry.c:972 +#: gtk/gtkentry.c:1003 msgid "GIcon for secondary icon" msgstr "GIcon for secondary icon" # -#: gtk/gtkentry.c:986 +#: gtk/gtkentry.c:1017 msgid "Primary storage type" -msgstr "ভান্ডাৰেৰ (Storage) ধৰন" +msgstr "ভান্ডাৰৰ (Storage) ধৰন" # -#: gtk/gtkentry.c:987 +#: gtk/gtkentry.c:1018 msgid "The representation being used for primary icon" msgstr "তথ্যচিত্ৰে বাবে যি উপস্থাপনা ব্যৱহাৰ কৰা হচ্ছে" # -#: gtk/gtkentry.c:1002 +#: gtk/gtkentry.c:1033 msgid "Secondary storage type" msgstr "সম্মুখগামী গৌণ স্টেপাৰ" # -#: gtk/gtkentry.c:1003 +#: gtk/gtkentry.c:1034 msgid "The representation being used for secondary icon" msgstr "তথ্যচিত্ৰে বাবে যি উপস্থাপনা ব্যৱহাৰ কৰা হচ্ছে" -#: gtk/gtkentry.c:1024 +#: gtk/gtkentry.c:1055 msgid "Primary icon activatable" msgstr "Primary icon activatable" # -#: gtk/gtkentry.c:1025 +#: gtk/gtkentry.c:1056 msgid "Whether the primary icon is activatable" msgstr "কামটো সক্ৰিয় হয় নে নহয়" # -#: gtk/gtkentry.c:1045 +#: gtk/gtkentry.c:1076 msgid "Secondary icon activatable" -msgstr "কাৰ্সাৰ আঁকায় ব্যৱহৃত দ্বিতীয় ৰং" +msgstr "কাৰ্ছাৰ আঁকায় ব্যৱহৃত দ্বিতীয় ৰং" # -#: gtk/gtkentry.c:1046 +#: gtk/gtkentry.c:1077 msgid "Whether the secondary icon is activatable" msgstr "কামটো সক্ৰিয় হয় নে নহয়" # -#: gtk/gtkentry.c:1068 +#: gtk/gtkentry.c:1099 msgid "Primary icon sensitive" msgstr "সেল sensitive প্ৰদৰ্শন কৰো" # -#: gtk/gtkentry.c:1069 +#: gtk/gtkentry.c:1100 msgid "Whether the primary icon is sensitive" msgstr "" "তালিকাৰ সদস্যদেৰ মিলিয়ে দেখাৰ সময় বড় বা ছোট হাতেৰ অক্ষৰ পৃথকভাবে বিবেচনা কৰা " "হ'ব নে নাই" # -#: gtk/gtkentry.c:1090 +#: gtk/gtkentry.c:1121 msgid "Secondary icon sensitive" msgstr "দ্বিতীয় Text" # -#: gtk/gtkentry.c:1091 +#: gtk/gtkentry.c:1122 msgid "Whether the secondary icon is sensitive" msgstr "কামটো সক্ৰিয় হয় নে নহয়" # -#: gtk/gtkentry.c:1107 +#: gtk/gtkentry.c:1138 msgid "Primary icon tooltip text" msgstr "সেল sensitive প্ৰদৰ্শন কৰো" # -#: gtk/gtkentry.c:1108 gtk/gtkentry.c:1144 +#: gtk/gtkentry.c:1139 gtk/gtkentry.c:1175 msgid "The contents of the tooltip on the primary icon" msgstr "সৰ্বমোট উল্লিখিত সময় অবধি" # -#: gtk/gtkentry.c:1124 +#: gtk/gtkentry.c:1155 msgid "Secondary icon tooltip text" -msgstr "কাৰ্সাৰ আঁকায় ব্যৱহৃত দ্বিতীয় ৰং" +msgstr "কাৰ্ছাৰ আঁকায় ব্যৱহৃত দ্বিতীয় ৰং" # -#: gtk/gtkentry.c:1125 gtk/gtkentry.c:1163 +#: gtk/gtkentry.c:1156 gtk/gtkentry.c:1194 msgid "The contents of the tooltip on the secondary icon" msgstr "সৰ্বমোট উল্লিখিত সময় অবধি" # -#: gtk/gtkentry.c:1143 +#: gtk/gtkentry.c:1174 msgid "Primary icon tooltip markup" msgstr "তালিকা সৰ্বমোট" # -#: gtk/gtkentry.c:1162 +#: gtk/gtkentry.c:1193 msgid "Secondary icon tooltip markup" msgstr "দ্বিতীয় Text" # -#: gtk/gtkentry.c:1182 gtk/gtktextview.c:681 +#: gtk/gtkentry.c:1213 gtk/gtktextview.c:682 msgid "IM module" msgstr "অবিকল্পিত প্ৰস্থ" # -#: gtk/gtkentry.c:1183 gtk/gtktextview.c:682 +#: gtk/gtkentry.c:1214 gtk/gtktextview.c:683 msgid "Which IM module should be used" msgstr "পেলেট ব্যৱহৃত হ'ব নে নাই" # -#: gtk/gtkentry.c:1197 +#: gtk/gtkentry.c:1228 msgid "Icon Prelight" msgstr "উচ্চতা" # -#: gtk/gtkentry.c:1198 +#: gtk/gtkentry.c:1229 msgid "Whether activatable icons should prelight when hovered" msgstr "ট্যাব প্ৰদৰ্শন কৰা হ'ব নে নাই" # -#: gtk/gtkentry.c:1211 +#: gtk/gtkentry.c:1242 msgid "Progress Border" msgstr "দীৰ্ঘ বক্সৰ প্ৰান্ত" # -#: gtk/gtkentry.c:1212 +#: gtk/gtkentry.c:1243 msgid "Border around the progress bar" msgstr "প্ৰগ্ৰেছবাৰত যি লিপি প্ৰদৰ্শন কৰা হ'ব" -#: gtk/gtkentry.c:1683 +#: gtk/gtkentry.c:1714 msgid "Border between text and frame." msgstr "Border." # -#: gtk/gtkentry.c:1697 +#: gtk/gtkentry.c:1728 msgid "State Hint" msgstr "অবস্থা বাক্য" # -#: gtk/gtkentry.c:1698 +#: gtk/gtkentry.c:1729 msgid "Whether to pass a proper state when drawing shadow or background" msgstr "টেক্সটৰ পটভূমি আঁকাৰ সময় যি বিটম্যাপকে মাস্ক হিচাপে ব্যৱহাৰ কৰা হ'ব" -#: gtk/gtkentry.c:1703 gtk/gtklabel.c:830 +#: gtk/gtkentry.c:1734 gtk/gtklabel.c:848 msgid "Select on focus" msgstr "ফোকাস কৰলে চিহ্নিত হ'ব" -#: gtk/gtkentry.c:1704 +#: gtk/gtkentry.c:1735 msgid "Whether to select the contents of an entry when it is focused" msgstr "কোন অন্তৰ্ভুক্তিৰ (Entry) অভ্যন্তৰীণ বস্তুকে ফ'কাচ কৰলে তা চিহ্নিত হ'ব নে নাই" -#: gtk/gtkentry.c:1718 +#: gtk/gtkentry.c:1749 msgid "Password Hint Timeout" msgstr "গুপ্তশব্দ" -#: gtk/gtkentry.c:1719 +#: gtk/gtkentry.c:1750 msgid "How long to show the last input character in hidden entries" msgstr "শেষ" +#: gtk/gtkentrybuffer.c:354 +msgid "The contents of the buffer" +msgstr "বাফাৰৰ বিষয়বস্তু" + +#: gtk/gtkentrybuffer.c:369 +msgid "Length of the text currently in the buffer" +msgstr "বাফাৰত থকা টেকস্টৰ দৈৰ্ঘ্য" + #: gtk/gtkentrycompletion.c:279 msgid "Completion Model" msgstr "সমাপ্তি মডেল" @@ -2527,13 +2571,13 @@ msgstr "মূলশব্দেৰ (Key) সৰ্বনিম্ন দৈৰ msgid "Minimum length of the search key in order to look up matches" msgstr "মিল খোঁজায় ব্যৱহৃত মূলশব্দেৰ (Key) সৰ্বনিম্ন দৈৰ্ঘ্য" -#: gtk/gtkentrycompletion.c:303 gtk/gtkiconview.c:585 +#: gtk/gtkentrycompletion.c:303 gtk/gtkiconview.c:586 msgid "Text column" msgstr "টেক্সট স্তম্ভ" #: gtk/gtkentrycompletion.c:304 msgid "The column of the model containing the strings." -msgstr "মডেলেৰ যি স্তম্ভে পঙ্‌ক্তি আছে।" +msgstr "মডেলৰ যি স্তম্ভে পঙ্‌ক্তি আছে।" #: gtk/gtkentrycompletion.c:323 msgid "Inline completion" @@ -2557,7 +2601,7 @@ msgstr "পপ-আপ সেট তৰ প্ৰস্থ" #: gtk/gtkentrycompletion.c:355 msgid "If TRUE, the popup window will have the same size as the entry" -msgstr "এটিৰ মান সত্য (TRUE) হলে, পপ-আপ উইন্ডোৰ আকাৰ হ'ব এন্ট্ৰিৰ আকাৰেৰ সমান" +msgstr "এটিৰ মান সত্য (TRUE) হলে, পপ-আপ উইন্ডোৰ আকাৰ হ'ব এন্ট্ৰিৰ আকাৰৰ সমান" #: gtk/gtkentrycompletion.c:373 msgid "Popup single match" @@ -2565,7 +2609,7 @@ msgstr "পপ-আপ এটা মিল" #: gtk/gtkentrycompletion.c:374 msgid "If TRUE, the popup window will appear for a single match." -msgstr "এটিৰ মান সত্য (TRUE) হলে, এটা মিলেৰ বাবে পপ-আপ উইন্ডো আবিৰ্ভূত হ'ব।" +msgstr "এটিৰ মান সত্য (TRUE) হলে, এটা মিলৰ বাবে পপ-আপ উইন্ডো আবিৰ্ভূত হ'ব।" #: gtk/gtkentrycompletion.c:388 msgid "Inline selection" @@ -2606,15 +2650,15 @@ msgstr "চাইল্ড উইজেটটি দেখানোৰ বাব #: gtk/gtkexpander.c:196 msgid "Text of the expander's label" -msgstr "এক্সপেন্ডাৰেৰ লেবেলেৰ ওপৰতে লেখা টেক্সট" +msgstr "এক্সপেন্ডাৰৰ লেবেলৰ ওপৰতে লেখা টেক্সট" -#: gtk/gtkexpander.c:211 gtk/gtklabel.c:509 +#: gtk/gtkexpander.c:211 gtk/gtklabel.c:510 msgid "Use markup" msgstr "মাৰ্কআপ ব্যৱহাৰ কৰো" -#: gtk/gtkexpander.c:212 gtk/gtklabel.c:510 +#: gtk/gtkexpander.c:212 gtk/gtklabel.c:511 msgid "The text of the label includes XML markup. See pango_parse_markup()" -msgstr "লেবেলেৰ টেক্সটে এক্সএমএল মাৰ্ক আপ অন্তৰ্ভুক্ত আছে। pango_parse_markup() দেখুন" +msgstr "লেবেলৰ টেক্সটে এক্সএমএল মাৰ্ক আপ অন্তৰ্ভুক্ত আছে। pango_parse_markup() দেখুন" #: gtk/gtkexpander.c:220 msgid "Space to put between the label and the child" @@ -2626,13 +2670,13 @@ msgstr "লেবেল উইজেট" #: gtk/gtkexpander.c:230 msgid "A widget to display in place of the usual expander label" -msgstr "স্বাভাবিক এক্সপেন্ডাৰেৰ লেবেলেৰ পৰিবৰ্তে যি উইজেটটি প্ৰদৰ্শিত হ'ব" +msgstr "স্বাভাবিক এক্সপেন্ডাৰৰ লেবেলৰ পৰিবৰ্তে যি উইজেটটি প্ৰদৰ্শিত হ'ব" -#: gtk/gtkexpander.c:236 gtk/gtktreeview.c:783 +#: gtk/gtkexpander.c:236 gtk/gtktreeview.c:774 msgid "Expander Size" msgstr "অধিকৃতি দৈৰ্ঘ্য" -#: gtk/gtkexpander.c:237 gtk/gtktreeview.c:784 +#: gtk/gtkexpander.c:237 gtk/gtktreeview.c:775 msgid "Size of the expander arrow" msgstr "অধিকৃতি চিহ্নেৰ দৈৰ্ঘ্য" @@ -2642,11 +2686,11 @@ msgstr "অধিকৃতি চিহ্নেৰ পাৰিপাৰ্শ #: gtk/gtkfilechooser.c:194 msgid "Action" -msgstr "কাজ" +msgstr "কাম" #: gtk/gtkfilechooser.c:195 msgid "The type of operation that the file selector is performing" -msgstr "এই ফাইল-নিৰ্বাচকটি যি ধৰনেৰ কাজ কৰছে" +msgstr "এই ফাইল-নিৰ্বাচকটি যি ধৰনেৰ কাম কৰছে" #: gtk/gtkfilechooser.c:201 msgid "File System Backend" @@ -2663,8 +2707,8 @@ msgstr "ফিল্টাৰ" #: gtk/gtkfilechooser.c:208 msgid "The current filter for selecting which files are displayed" msgstr "" -"যি সকল ফাইলেৰ নাম দেখানো হ'ব, তাদেৰ বাছাই কৰাৰ কাজে বৰ্তমানে যি ফিল্টাৰটি " -"ব্যৱহৃত হচ্ছে" +"যি সকল ফাইলৰ নাম দেখানো হ'ব, তাদেৰ বাছাই কৰাৰ কামে বৰ্তমানে যি ফিল্টাৰটি ব্যৱহৃত " +"হচ্ছে" #: gtk/gtkfilechooser.c:213 msgid "Local Only" @@ -2672,7 +2716,7 @@ msgstr "অকল স্থানীয়" #: gtk/gtkfilechooser.c:214 msgid "Whether the selected file(s) should be limited to local file: URLs" -msgstr "ফাইল বাছাইকৰণ অকল স্থানীয়ৰ ফাইলেৰ মাজতই সীমাবদ্ধ থাকবে নে নাই: ইউআৰএল" +msgstr "ফাইল বাছাইকৰণ অকল স্থানীয়ৰ ফাইলৰ মাজতই সীমাবদ্ধ থাকবে নে নাই: ইউআৰএল" #: gtk/gtkfilechooser.c:219 msgid "Preview widget" @@ -2680,7 +2724,7 @@ msgstr "প্ৰাকদৰ্শনে ব্যৱহৃত উইজেট" #: gtk/gtkfilechooser.c:220 msgid "Application supplied widget for custom previews." -msgstr "স্বনিৰ্বাচিত প্ৰাকদৰ্শনে ব্যৱহাৰেৰ বাবে অ্যাপলিকেশন কৰ্তৃক সৰবৰাহকৃত উইজেট।" +msgstr "স্বনিৰ্বাচিত প্ৰাকদৰ্শনে ব্যৱহাৰৰ বাবে অ্যাপলিকেশন কৰ্তৃক সৰবৰাহকৃত উইজেট।" #: gtk/gtkfilechooser.c:225 msgid "Preview Widget Active" @@ -2690,7 +2734,7 @@ msgstr "প্ৰাকদৰ্শনে ব্যৱহৃত উইজেট msgid "" "Whether the application supplied widget for custom previews should be shown." msgstr "" -"স্বনিৰ্বাচিত প্ৰাকদৰ্শনে ব্যৱহাৰেৰ বাবে অ্যাপলিকেশন কৰ্তৃক সৰবৰাহকৃত উইজেট প্ৰদৰ্শন কৰা " +"স্বনিৰ্বাচিত প্ৰাকদৰ্শনে ব্যৱহাৰৰ বাবে অ্যাপলিকেশন কৰ্তৃক সৰবৰাহকৃত উইজেট প্ৰদৰ্শন কৰা " "হ'ব নে নাই।" #: gtk/gtkfilechooser.c:231 @@ -2700,7 +2744,7 @@ msgstr "প্ৰাকদৰ্শনে ব্যৱহৃত লেবেল #: gtk/gtkfilechooser.c:232 msgid "Whether to display a stock label with the name of the previewed file." msgstr "" -"প্ৰাকদৰ্শনকৃত ফাইলেৰ নামেৰ সাহায্যি এটা স্টক (Stock) লেবেল প্ৰদৰ্শন কৰা হ'ব নে নাই।" +"প্ৰাকদৰ্শনকৃত ফাইলৰ নামেৰ সহায়ত এটা স্টক (Stock) লেবেল প্ৰদৰ্শন কৰা হ'ব নে নাই।" #: gtk/gtkfilechooser.c:237 msgid "Extra widget" @@ -2716,7 +2760,7 @@ msgstr "একাধিক জিনিষ বাছাই কৰো" #: gtk/gtkfilechooser.c:244 gtk/gtkfilesel.c:541 msgid "Whether to allow multiple files to be selected" -msgstr "একাধিক ফাইলকে চিহ্নিত কৰা যাবে নে নাই" +msgstr "একাধিক ফাইলকে চিহ্নিত কৰা যাব নে নাই" #: gtk/gtkfilechooser.c:250 msgid "Show Hidden" @@ -2736,6 +2780,17 @@ msgid "" "dialog if necessary." msgstr "ফাইল মোড." +#: gtk/gtkfilechooser.c:283 +msgid "Allow folders creation" +msgstr "ফোল্ডাৰৰ সৃষ্টিৰ অনুমতি দিয়ক" + +#: gtk/gtkfilechooser.c:284 +msgid "" +"Whether a file chooser not in open mode will offer the user to create new " +"folders." +msgstr "" +"খোলা মোডত নথকা নথিপত্ৰ নিৰ্বাচকে ব্যৱহাৰকৰ্তাক নতুন ফোল্ডাৰ সৃষ্টি কৰিব দিব নে নাই ।" + #: gtk/gtkfilechooserbutton.c:376 msgid "Dialog" msgstr "ডায়ালগ" @@ -2753,9 +2808,9 @@ msgid "The desired width of the button widget, in characters." msgstr "অক্ষৰ হিচাপে বুটাম উইজেটেৰ আকাঙ্খিত প্ৰস্থ।" #: gtk/gtkfilesel.c:526 gtk/gtkimage.c:163 gtk/gtkrecentmanager.c:214 -#: gtk/gtkstatusicon.c:218 +#: gtk/gtkstatusicon.c:221 msgid "Filename" -msgstr "ফাইলেৰ নাম" +msgstr "ফাইলৰ নাম" #: gtk/gtkfilesel.c:527 msgid "The currently selected filename" @@ -2763,7 +2818,7 @@ msgstr "বৰ্তমানে বাছাইকৃত ফাইলনাম" #: gtk/gtkfilesel.c:533 msgid "Show file operations" -msgstr "ফাইল সংক্ৰান্ত কাজকৰ্ম দেখানো হোক" +msgstr "ফাইল সংক্ৰান্ত কামকৰ্ম দেখানো হোক" #: gtk/gtkfilesel.c:534 msgid "Whether buttons for creating/manipulating files should be displayed" @@ -2807,7 +2862,7 @@ msgstr "লেবেল ফন্ট ব্যৱহাৰ কৰো" #: gtk/gtkfontbutton.c:176 msgid "Whether the label is drawn in the selected font" -msgstr "নিৰ্বাচিত ফন্টৰ সাহায্যি লেবেলে লেখা হ'ব নে নাই" +msgstr "নিৰ্বাচিত ফন্টৰ সহায়ত লেবেলে লেখা হ'ব নে নাই" #: gtk/gtkfontbutton.c:191 msgid "Use size in label" @@ -2836,7 +2891,7 @@ msgstr "নিৰ্বাচিত ফন্টৰ আকাৰ লেবেল # #: gtk/gtkfontsel.c:197 msgid "The string that represents this font" -msgstr "যি এক্স অক্ষীয় পঙ্‌ক্তিটি এই ফন্টৰ প্ৰতিনিধিত্ব কৰে" +msgstr "যি এক্স অক্ষীয় পঙ্‌ক্তিটি এই ফন্টৰ প্ৰতিনিধিত্ব কৰি" #: gtk/gtkfontsel.c:204 msgid "The GdkFont that is currently selected" @@ -2860,7 +2915,7 @@ msgstr "শিৰোনাম" #: gtk/gtkframe.c:114 msgid "The horizontal alignment of the label" -msgstr "লেবেলেৰ পথালি সংৰেখন" +msgstr "লেবেলৰ পথালি সংৰেখন" #: gtk/gtkframe.c:122 msgid "Label yalign" @@ -2868,7 +2923,7 @@ msgstr "শিৰোনাম" #: gtk/gtkframe.c:123 msgid "The vertical alignment of the label" -msgstr "লেবেলেৰ উলম্ব সংৰেখন" +msgstr "লেবেলৰ উলম্ব সংৰেখন" #: gtk/gtkframe.c:131 gtk/gtkhandlebox.c:167 msgid "Deprecated property, use shadow_type instead" @@ -2881,11 +2936,11 @@ msgstr "ফ্ৰেমেৰ ছায়া" #: gtk/gtkframe.c:139 msgid "Appearance of the frame border" -msgstr "ফ্ৰেম প্ৰান্তেৰ চেহাৰা" +msgstr "ফ্ৰেম প্ৰান্তৰ চেহাৰা" #: gtk/gtkframe.c:148 msgid "A widget to display in place of the usual frame label" -msgstr "সাধাৰণত প্ৰদৰ্শিত ফ্ৰেম লেবেলেৰ পৰিবৰ্তে যি উইজেটটি দেখানো হ'ব" +msgstr "সাধাৰণত প্ৰদৰ্শিত ফ্ৰেম লেবেলৰ পৰিবৰ্তে যি উইজেটটি দেখানো হ'ব" #: gtk/gtkhandlebox.c:175 msgid "Appearance of the shadow that surrounds the container" @@ -2893,11 +2948,11 @@ msgstr "কনটেইনাৰকে ঘিৰে থাকা ছায়াৰ #: gtk/gtkhandlebox.c:183 msgid "Handle position" -msgstr "হাতলেৰ অবস্থান" +msgstr "হাতলৰ অবস্থান" #: gtk/gtkhandlebox.c:184 msgid "Position of the handle relative to the child widget" -msgstr "চাইল্ড উইজেটেৰ সাপেক্ষে হাতলেৰ অবস্থান" +msgstr "চাইল্ড উইজেটেৰ সাপেক্ষে হাতলৰ অবস্থান" #: gtk/gtkhandlebox.c:192 msgid "Snap edge" @@ -2907,11 +2962,11 @@ msgstr "উজ্জ্বল প্ৰান্ত" msgid "" "Side of the handlebox that's lined up with the docking point to dock the " "handlebox" -msgstr "হ্যান্ডলবাক্সৰ পাৰ্শ্ব যা ডকিং পয়েন্টেৰ সৈতে যুক্ত হয়" +msgstr "হ্যান্ডলবাক্সৰ পাৰ্শ্ব যাৰ ডকিং পয়েন্টেৰ সৈতে যুক্ত হয়" #: gtk/gtkhandlebox.c:201 msgid "Snap edge set" -msgstr "উজ্জ্বল প্ৰান্তেৰ সেট" +msgstr "উজ্জ্বল প্ৰান্তৰ সেট" #: gtk/gtkhandlebox.c:202 msgid "" @@ -2932,100 +2987,100 @@ msgstr "" "A boolean value indicating whether the handlebox's child is attached or " "detached." -#: gtk/gtkiconview.c:548 +#: gtk/gtkiconview.c:549 msgid "Selection mode" msgstr "Selection mode" -#: gtk/gtkiconview.c:549 +#: gtk/gtkiconview.c:550 msgid "The selection mode" msgstr "বাছাইকৰণ মোড" -#: gtk/gtkiconview.c:567 +#: gtk/gtkiconview.c:568 msgid "Pixbuf column" msgstr "পিক্সবাফ স্তম্ভ" -#: gtk/gtkiconview.c:568 +#: gtk/gtkiconview.c:569 msgid "Model column used to retrieve the icon pixbuf from" -msgstr "মডেল স্তম্ভ ব্যৱহাৰ কৰে যিখানৰ পৰা আইকন পিক্সবাফ আহৰণ কৰা হৈছে - " +msgstr "মডেল স্তম্ভ ব্যৱহাৰ কৰি যিখানৰ পৰা আইকন পিক্সবাফ আহৰণ কৰা হৈছে - " -#: gtk/gtkiconview.c:586 +#: gtk/gtkiconview.c:587 msgid "Model column used to retrieve the text from" -msgstr "মডেল স্তম্ভ ব্যৱহাৰ কৰে যিখানৰ পৰা টেক্সট আহৰণ কৰা হৈছে - " +msgstr "মডেল স্তম্ভ ব্যৱহাৰ কৰি যিখানৰ পৰা টেক্সট আহৰণ কৰা হৈছে - " -#: gtk/gtkiconview.c:605 +#: gtk/gtkiconview.c:606 msgid "Markup column" msgstr "মাৰ্কআপ স্তম্ভ" -#: gtk/gtkiconview.c:606 +#: gtk/gtkiconview.c:607 msgid "Model column used to retrieve the text if using Pango markup" -msgstr "পেনগো মাৰ্কআপ ব্যৱহাৰ কৰলে মডেল স্তম্ভ ব্যৱহাৰ কৰে টেক্সট আহৰণ কৰা হয়" +msgstr "পেনগো মাৰ্কআপ ব্যৱহাৰ কৰলে মডেল স্তম্ভ ব্যৱহাৰ কৰি টেক্সট আহৰণ কৰা হয়" -#: gtk/gtkiconview.c:613 +#: gtk/gtkiconview.c:614 msgid "Icon View Model" msgstr "আইকন-ভিউ মডেল" -#: gtk/gtkiconview.c:614 +#: gtk/gtkiconview.c:615 msgid "The model for the icon view" msgstr "আইকন-ভিউ তৰ মডেল" -#: gtk/gtkiconview.c:630 +#: gtk/gtkiconview.c:631 msgid "Number of columns" msgstr "স্তম্ভ সংখ্যা" -#: gtk/gtkiconview.c:631 +#: gtk/gtkiconview.c:632 msgid "Number of columns to display" msgstr "যি সংখ্যক স্তম্ভ প্ৰদৰ্শন কৰা হ'ব" -#: gtk/gtkiconview.c:648 +#: gtk/gtkiconview.c:649 msgid "Width for each item" msgstr "প্ৰতিটি বস্তুৰ প্ৰস্থ" -#: gtk/gtkiconview.c:649 +#: gtk/gtkiconview.c:650 msgid "The width used for each item" msgstr "প্ৰতিটি বস্তুৰ প্ৰস্থ" -#: gtk/gtkiconview.c:665 +#: gtk/gtkiconview.c:666 msgid "Space which is inserted between cells of an item" msgstr "প্ৰতিটি বস্তুৰ ঘৰগুলোৰ মাজত যি সংখ্যক স্থান ভৰোৱা হয়" -#: gtk/gtkiconview.c:680 +#: gtk/gtkiconview.c:681 msgid "Row Spacing" msgstr "শাৰীৰ স্থান তৰ সংখ্যা" -#: gtk/gtkiconview.c:681 +#: gtk/gtkiconview.c:682 msgid "Space which is inserted between grid rows" msgstr "গ্ৰীড শাৰীগুলোৰ মাজত যি সংখ্যক স্থান ভৰোৱা হয়" -#: gtk/gtkiconview.c:696 +#: gtk/gtkiconview.c:697 msgid "Column Spacing" msgstr "শাৰীৰ স্থান তৰ সংখ্যা" -#: gtk/gtkiconview.c:697 +#: gtk/gtkiconview.c:698 msgid "Space which is inserted between grid columns" msgstr "হলো স্তম্ভ" -#: gtk/gtkiconview.c:712 +#: gtk/gtkiconview.c:713 msgid "Margin" msgstr "মাৰ্জিন" -#: gtk/gtkiconview.c:713 +#: gtk/gtkiconview.c:714 msgid "Space which is inserted at the edges of the icon view" msgstr "আইকন-ভিউ তৰ প্ৰান্তে যি সংখ্যক স্থান ভৰোৱা হয়" #: gtk/gtkiconview.c:730 msgid "" "How the text and icon of each item are positioned relative to each other" -msgstr "প্ৰতিটি বস্তুৰ আইকন আৰু টেক্সটকে পৰস্পৰেৰ সাপেক্ষে যি ভাবে ৰাখা হয়" +msgstr "প্ৰতিটি বস্তুৰ আইকন আৰু টেক্সটক পৰস্পৰৰ সাপেক্ষে যি ভাবে ৰাখা হয়" -#: gtk/gtkiconview.c:746 gtk/gtktreeview.c:618 gtk/gtktreeviewcolumn.c:307 +#: gtk/gtkiconview.c:746 gtk/gtktreeview.c:609 gtk/gtktreeviewcolumn.c:308 msgid "Reorderable" -msgstr "পুনৰায় সাজানোৰ যোগ্য" +msgstr "পুনৰায় সজোৱাৰ যোগ্য" -#: gtk/gtkiconview.c:747 gtk/gtktreeview.c:619 +#: gtk/gtkiconview.c:747 gtk/gtktreeview.c:610 msgid "View is reorderable" -msgstr "প্ৰদৰ্শিত দৃশ্য পুনৰায় সাজানোৰ যোগ্য" +msgstr "প্ৰদৰ্শিত দৃশ্য পুনৰায় সজোৱাৰ যোগ্য" -#: gtk/gtkiconview.c:754 gtk/gtktreeview.c:769 +#: gtk/gtkiconview.c:754 gtk/gtktreeview.c:760 msgid "Tooltip Column" msgstr "টুলটিপ স্তম্ভ" @@ -3033,27 +3088,35 @@ msgstr "টুলটিপ স্তম্ভ" msgid "The column in the model containing the tooltip texts for the items" msgstr "উল্লিখিত সময় অবধি" -#: gtk/gtkiconview.c:766 +#: gtk/gtkiconview.c:772 +msgid "Item Padding" +msgstr "বস্তুৰ পেডিং" + +#: gtk/gtkiconview.c:773 +msgid "Padding around icon view items" +msgstr "আইকন প্ৰদৰ্শন বস্তুৰ ওচৰত পেডিং" + +#: gtk/gtkiconview.c:782 msgid "Selection Box Color" msgstr "নিৰ্বাচক বক্সৰ ৰং" -#: gtk/gtkiconview.c:767 +#: gtk/gtkiconview.c:783 msgid "Color of the selection box" msgstr "নিৰ্বাচক বক্সৰ ৰং" -#: gtk/gtkiconview.c:773 +#: gtk/gtkiconview.c:789 msgid "Selection Box Alpha" msgstr "নিৰ্বাচক বক্সৰ আলফা" -#: gtk/gtkiconview.c:774 +#: gtk/gtkiconview.c:790 msgid "Opacity of the selection box" msgstr "নিৰ্বাচক বক্সৰ স্বচ্ছতা" -#: gtk/gtkimage.c:131 gtk/gtkstatusicon.c:210 +#: gtk/gtkimage.c:131 gtk/gtkstatusicon.c:213 msgid "Pixbuf" msgstr "পিক্সবাফ" -#: gtk/gtkimage.c:132 gtk/gtkstatusicon.c:211 +#: gtk/gtkimage.c:132 gtk/gtkstatusicon.c:214 msgid "A GdkPixbuf to display" msgstr "প্ৰদৰ্শনেৰ বাবে এটা GdkPixbuf" @@ -3079,13 +3142,13 @@ msgstr "ছাঁচ" #: gtk/gtkimage.c:156 msgid "Mask bitmap to use with GdkImage or GdkPixmap" -msgstr "GdkImage বা GdkPixmap ইয়াৰ সৈতে ব্যৱহাৰেৰ বাবে মাস্ক" +msgstr "GdkImage বা GdkPixmap ইয়াৰ সৈতে ব্যৱহাৰৰ বাবে মাস্ক" -#: gtk/gtkimage.c:164 gtk/gtkstatusicon.c:219 +#: gtk/gtkimage.c:164 gtk/gtkstatusicon.c:222 msgid "Filename to load and display" -msgstr "লোড কৰে দেখাবাৰ বাবে ফাইলেৰ নাম" +msgstr "লোড কৰি দেখাবাৰ বাবে ফাইলৰ নাম" -#: gtk/gtkimage.c:173 gtk/gtkstatusicon.c:227 +#: gtk/gtkimage.c:173 gtk/gtkstatusicon.c:230 msgid "Stock ID for a stock image to display" msgstr "যি স্টক চিত্ৰটি প্ৰদৰ্শন কৰা হ'ব তাৰ স্টক আইডি" @@ -3122,22 +3185,22 @@ msgstr "আ্যনিমেশন" msgid "GdkPixbufAnimation to display" msgstr "যি GdkPixbufAnimation প্ৰদৰ্শন কৰা হ'ব" -#: gtk/gtkimage.c:255 gtk/gtkstatusicon.c:258 +#: gtk/gtkimage.c:255 gtk/gtkstatusicon.c:261 msgid "Storage type" -msgstr "ভান্ডাৰেৰ (Storage) ধৰন" +msgstr "ভান্ডাৰৰ (Storage) ধৰন" -#: gtk/gtkimage.c:256 gtk/gtkstatusicon.c:259 +#: gtk/gtkimage.c:256 gtk/gtkstatusicon.c:262 msgid "The representation being used for image data" msgstr "তথ্যচিত্ৰে বাবে যি উপস্থাপনা ব্যৱহাৰ কৰা হচ্ছে" #: gtk/gtkimagemenuitem.c:136 msgid "Child widget to appear next to the menu text" -msgstr "মেনু টেক্সটৰ পাশে যি চাইল্ড উইজেট দেখা যাবে" +msgstr "মেনু টেক্সটৰ পাশে যি চাইল্ড উইজেট দেখা যাব" # #: gtk/gtkimagemenuitem.c:151 msgid "Whether to use the label text to create a stock menu item" -msgstr "মাউসেৰ সাহায্যি লেবেলেৰ টেক্সটকে চিহ্নিত কৰা যাবে নে নাই" +msgstr "মাউছৰ সহায়ত লেবেলৰ টেক্সটক চিহ্নিত কৰা যাব নে নাই" #: gtk/gtkimagemenuitem.c:169 msgid "Always show image" @@ -3149,7 +3212,7 @@ msgid "Whether the image will always be shown" msgstr "Whether the image will always be shown" # -#: gtk/gtkimagemenuitem.c:184 gtk/gtkmenu.c:515 +#: gtk/gtkimagemenuitem.c:184 gtk/gtkmenu.c:516 msgid "Accel Group" msgstr "Accel Group" @@ -3166,82 +3229,102 @@ msgstr "Show menu images" msgid "Whether images should be shown in menus" msgstr "Whether images should be shown in menus" +#: gtk/gtkinfobar.c:384 gtk/gtkmessagedialog.c:128 +msgid "Message Type" +msgstr "বাৰ্তাৰ ধৰন" + +#: gtk/gtkinfobar.c:385 gtk/gtkmessagedialog.c:129 +msgid "The type of message" +msgstr "বাৰ্তাৰ ধৰন" + +#: gtk/gtkinfobar.c:440 +msgid "Width of border around the content area" +msgstr "বিষয়বস্তুৰ ক্ষেত্ৰৰ ওচৰৰ প্ৰান্তৰ প্ৰস্থ" + +#: gtk/gtkinfobar.c:457 +msgid "Spacing between elements of the area" +msgstr "ক্ষেত্ৰত পদাৰ্থৰ মাজৰ ৰিক্ত স্থান" + +#: gtk/gtkinfobar.c:489 +msgid "Width of border around the action area" +msgstr "কাৰ্য্যক্ষেত্ৰ ওচৰৰ প্ৰান্তৰ প্ৰস্থ" + #: gtk/gtkinvisible.c:87 gtk/gtkwindow.c:615 msgid "The screen where this window will be displayed" msgstr "এই উইন্ডোটি যি পৰ্দ্দায় প্ৰদৰ্শিত হ'ব" -#: gtk/gtklabel.c:496 +#: gtk/gtklabel.c:497 msgid "The text of the label" -msgstr "লেবেলেৰ টেক্সট" +msgstr "লেবেলৰ টেক্সট" -#: gtk/gtklabel.c:503 +#: gtk/gtklabel.c:504 msgid "A list of style attributes to apply to the text of the label" -msgstr "লেবেলেৰ টেক্সটে প্ৰয়োগ কৰাৰ মত কিছু বৈশিষ্ট্যিৰ এটা তালিকা" +msgstr "লেবেলৰ টেক্সটে প্ৰয়োগ কৰাৰ মত কিছু বৈশিষ্ট্যিৰ এটা তালিকা" -#: gtk/gtklabel.c:524 gtk/gtktexttag.c:359 gtk/gtktextview.c:590 +#: gtk/gtklabel.c:525 gtk/gtktexttag.c:359 gtk/gtktextview.c:591 msgid "Justification" msgstr "সমপ্ৰান্ত নিৰ্ধাৰণ" -#: gtk/gtklabel.c:525 +#: gtk/gtklabel.c:526 msgid "" "The alignment of the lines in the text of the label relative to each other. " "This does NOT affect the alignment of the label within its allocation. See " "GtkMisc::xalign for that" msgstr "" -"লেবেলেৰ টেক্সটৰ লাইনগুলোৰ সংৰেখন পৰস্পৰেৰ সাপেক্ষে। ইয়াক লেবেলেৰ সংৰেখনকে " -"প্ৰভাবিত কৰে না। এবাবে GtkMisc::xalign দেখুন" +"লেবেলৰ টেক্সটৰ লাইনগুলোৰ সংৰেখন পৰস্পৰৰ সাপেক্ষে। ইয়াক লেবেলৰ সংৰেখনকে প্ৰভাবিত " +"কৰি না। এবাবে GtkMisc::xalign দেখুন" -#: gtk/gtklabel.c:533 +#: gtk/gtklabel.c:534 msgid "Pattern" msgstr "পেটাৰ্ন" -#: gtk/gtklabel.c:534 +#: gtk/gtklabel.c:535 msgid "" "A string with _ characters in positions correspond to characters in the text " "to underline" msgstr "এই পঙ্‌ক্তিটিৰ যিসব স্থানে _ আছে, টেক্সটৰ সেসব স্থানেৰ অক্ষৰ নিম্নৰেখাঙ্কিত হ'ব" -#: gtk/gtklabel.c:541 +#: gtk/gtklabel.c:542 msgid "Line wrap" msgstr "লাইন গুটানো" -#: gtk/gtklabel.c:542 +#: gtk/gtklabel.c:543 msgid "If set, wrap lines if the text becomes too wide" msgstr "এটি বাছাই কৰা থাকলে লাইনেৰ দৈৰ্ঘ্য অত্যধিক বেশি হয়ে গেলে লাইনটি গুটিয়ে যায়" -#: gtk/gtklabel.c:557 +#: gtk/gtklabel.c:558 msgid "Line wrap mode" msgstr "মোড" -#: gtk/gtklabel.c:558 +#: gtk/gtklabel.c:559 msgid "If wrap is set, controls how linewrapping is done" msgstr "হলো হলো" -#: gtk/gtklabel.c:565 +#: gtk/gtklabel.c:566 msgid "Selectable" msgstr "চিহ্নিত কৰাৰ যোগ্য" -#: gtk/gtklabel.c:566 +#: gtk/gtklabel.c:567 msgid "Whether the label text can be selected with the mouse" -msgstr "মাউসেৰ সাহায্যি লেবেলেৰ টেক্সটকে চিহ্নিত কৰা যাবে নে নাই" +msgstr "মাউছৰ সহায়ত লেবেলৰ টেক্সটক চিহ্নিত কৰা যাব নে নাই" -#: gtk/gtklabel.c:572 +#: gtk/gtklabel.c:573 msgid "Mnemonic key" msgstr "নেমোনিক কী (Key)" -#: gtk/gtklabel.c:573 +#: gtk/gtklabel.c:574 msgid "The mnemonic accelerator key for this label" -msgstr "এই লেবেলেৰ নেমোনিক গতিবৰ্ধক কী (Key)" +msgstr "এই লেবেলৰ নেমোনিক গতিবৰ্ধক কী (Key)" -#: gtk/gtklabel.c:581 +#: gtk/gtklabel.c:582 msgid "Mnemonic widget" msgstr "নেমোনিক উইজেট" -#: gtk/gtklabel.c:582 +#: gtk/gtklabel.c:583 msgid "The widget to be activated when the label's mnemonic key is pressed" -msgstr "লেবেলেৰ নেমোনিক কী (Key) চাপা হলে যি উইজেটকে সক্ৰিয় কৰা হ'ব" +msgstr "লেবেলৰ নেমোনিক কী (Key) চাপা হলে যি উইজেটকে সক্ৰিয় কৰা হ'ব" -#: gtk/gtklabel.c:628 +#: gtk/gtklabel.c:629 msgid "" "The preferred place to ellipsize the string, if the label does not have " "enough room to display the entire string" @@ -3249,31 +3332,39 @@ msgstr "" "The preferred place to ellipsize the string, if the label does not have " "enough room to display the entire string" -#: gtk/gtklabel.c:668 +#: gtk/gtklabel.c:669 msgid "Single Line Mode" msgstr "একক লাইন মোড" -#: gtk/gtklabel.c:669 +#: gtk/gtklabel.c:670 msgid "Whether the label is in single line mode" msgstr "লেবেলটি একক লাইন মোডে আছে নে নাই" -#: gtk/gtklabel.c:686 +#: gtk/gtklabel.c:687 msgid "Angle" msgstr "কোণ" -#: gtk/gtklabel.c:687 +#: gtk/gtklabel.c:688 msgid "Angle at which the label is rotated" msgstr "লেবেলকে যি কোণে ঘোৰানো হৈছে" -#: gtk/gtklabel.c:707 +#: gtk/gtklabel.c:708 msgid "Maximum Width In Characters" msgstr "অক্ষৰ হিচাপে সৰ্বোচ্চ প্ৰস্থ" -#: gtk/gtklabel.c:708 +#: gtk/gtklabel.c:709 msgid "The desired maximum width of the label, in characters" -msgstr "অক্ষৰ হিচাপে লেবেলেৰ সৰ্বোচ্চ আকাঙ্খিত প্ৰস্থ" +msgstr "অক্ষৰ হিচাপে লেবেলৰ সৰ্বোচ্চ আকাঙ্খিত প্ৰস্থ" -#: gtk/gtklabel.c:831 +#: gtk/gtklabel.c:727 +msgid "Track visited links" +msgstr "প্ৰদৰ্শন কৰা সংযোগক ট্ৰেক কৰক" + +#: gtk/gtklabel.c:728 +msgid "Whether visited links should be tracked" +msgstr "দৰ্শন কৰা সংযোগক ট্ৰেক কৰিব লাগে নে নাই" + +#: gtk/gtklabel.c:849 msgid "Whether to select the contents of a selectable label when it is focused" msgstr "সৰ্বমোট হলো" @@ -3321,176 +3412,187 @@ msgid "Whether this link has been visited." msgstr "কামটো দৃশ্যমান নে নাই।" # -#: gtk/gtkmenu.c:501 +#: gtk/gtkmenu.c:502 msgid "The currently selected menu item" msgstr "বৰ্তমানে বাছাইকৃত ফাইলনাম" # -#: gtk/gtkmenu.c:516 +#: gtk/gtkmenu.c:517 msgid "The accel group holding accelerators for the menu" -msgstr "এই লেবেলেৰ নেমোনিক গতিবৰ্ধক কী (Key)" +msgstr "এই লেবেলৰ নেমোনিক গতিবৰ্ধক কী (Key)" -#: gtk/gtkmenu.c:530 gtk/gtkmenuitem.c:285 +#: gtk/gtkmenu.c:531 gtk/gtkmenuitem.c:290 msgid "Accel Path" msgstr "Accel Path" -#: gtk/gtkmenu.c:531 +#: gtk/gtkmenu.c:532 msgid "An accel path used to conveniently construct accel paths of child items" msgstr "" "An accel path used to conveniently construct accel paths of child items" # -#: gtk/gtkmenu.c:547 +#: gtk/gtkmenu.c:548 msgid "Attach Widget" msgstr "অতিৰিক্ত উইজেট" # -#: gtk/gtkmenu.c:548 +#: gtk/gtkmenu.c:549 msgid "The widget the menu is attached to" msgstr "মেনুৰ বস্তুতে টিক দেয়া হৈছে নে নাই" -#: gtk/gtkmenu.c:556 +#: gtk/gtkmenu.c:557 msgid "" "A title that may be displayed by the window manager when this menu is torn-" "off" msgstr "" "এই মেনুটি বিচ্ছিন্ন (???) থাকলে উইন্ডো ম্যানেজাৰ যি শিৰোনামটি প্ৰদৰ্শন কৰতে পাৰবে" -#: gtk/gtkmenu.c:570 +#: gtk/gtkmenu.c:571 msgid "Tearoff State" msgstr "টিয়াৰ-অফ অবস্থা" -#: gtk/gtkmenu.c:571 +#: gtk/gtkmenu.c:572 msgid "A boolean that indicates whether the menu is torn-off" -msgstr "এটা বুলিয়ান মান যা নিৰ্দেশ কৰে যি মেনুটি বিচ্ছিন্ন নে নাই (Torn-off)" +msgstr "এটা বুলিয়ান মান যাৰ নিৰ্দেশ কৰি যি মেনুটি বিচ্ছিন্ন নে নাই (Torn-off)" # -#: gtk/gtkmenu.c:585 +#: gtk/gtkmenu.c:586 msgid "Monitor" msgstr "মণিটৰ" -#: gtk/gtkmenu.c:586 +#: gtk/gtkmenu.c:587 msgid "The monitor the menu will be popped up on" -msgstr "The monitor the menu will be popped up on" +msgstr "দেখুৱাব লগা তালিকা যি মণিটৰত ওলাব" -#: gtk/gtkmenu.c:592 +#: gtk/gtkmenu.c:593 msgid "Vertical Padding" msgstr "উলম্ব পেডিং (Padding)" -#: gtk/gtkmenu.c:593 +#: gtk/gtkmenu.c:594 msgid "Extra space at the top and bottom of the menu" msgstr "উইজেটেৰ ওপৰত আৰু নীচে যতগুলো স্থান যোগ কৰা হ'ব" -#: gtk/gtkmenu.c:601 +#: gtk/gtkmenu.c:616 +msgid "Reserve Toggle Size" +msgstr "টগলৰ আকাৰ ওভটাওক" + +#: gtk/gtkmenu.c:617 +msgid "" +"A boolean that indicates whether the menu reserves space for toggles and " +"icons" +msgstr "" +"এটা বুলিয়ান মান যাৰ নিৰ্দেশত টগল আৰু আইকণৰ কাৰণে তালিকা সংৰক্ষিত কৰা হ'ব নে নাই" + +#: gtk/gtkmenu.c:623 msgid "Horizontal Padding" msgstr "স্থান নষ্ট কৰা (Padding)" -#: gtk/gtkmenu.c:602 +#: gtk/gtkmenu.c:624 msgid "Extra space at the left and right edges of the menu" msgstr "সৰ্বমোট" -#: gtk/gtkmenu.c:610 +#: gtk/gtkmenu.c:632 msgid "Vertical Offset" msgstr "উলম্ব অফসেট" -#: gtk/gtkmenu.c:611 +#: gtk/gtkmenu.c:633 msgid "" "When the menu is a submenu, position it this number of pixels offset " "vertically" msgstr "এটি যদি সাবমেনু হয়, তেন্তে একে এই সংখ্যক পিক্সেল উলম্ব অফসেটে স্থাপন কৰো" -#: gtk/gtkmenu.c:619 +#: gtk/gtkmenu.c:641 msgid "Horizontal Offset" msgstr "পথালি অফসেট" -#: gtk/gtkmenu.c:620 +#: gtk/gtkmenu.c:642 msgid "" "When the menu is a submenu, position it this number of pixels offset " "horizontally" msgstr "এটি যদি সাবমেনু হয়, তেন্তে একে এই সংখ্যক পিক্সেল পথালি অফসেটে স্থাপন কৰো" -#: gtk/gtkmenu.c:628 +#: gtk/gtkmenu.c:650 msgid "Double Arrows" msgstr "Double Arrows" -#: gtk/gtkmenu.c:629 +#: gtk/gtkmenu.c:651 msgid "When scrolling, always show both arrows." msgstr "When scrolling, always show both arrows." # -#: gtk/gtkmenu.c:642 +#: gtk/gtkmenu.c:664 msgid "Arrow Placement" msgstr "এক্স অক্ষ বৰাবৰ তীৰচিহ্ন সৰানো" -#: gtk/gtkmenu.c:643 +#: gtk/gtkmenu.c:665 msgid "Indicates where scroll arrows should be placed" msgstr "Indicates where scroll arrows should be placed" -#: gtk/gtkmenu.c:651 +#: gtk/gtkmenu.c:673 msgid "Left Attach" msgstr "Left Attach" -#: gtk/gtkmenu.c:652 gtk/gtktable.c:174 +#: gtk/gtkmenu.c:674 gtk/gtktable.c:174 msgid "The column number to attach the left side of the child to" msgstr "The column number to attach the left side of the child to" -#: gtk/gtkmenu.c:659 +#: gtk/gtkmenu.c:681 msgid "Right Attach" msgstr "Right Attach" -#: gtk/gtkmenu.c:660 +#: gtk/gtkmenu.c:682 msgid "The column number to attach the right side of the child to" msgstr "The column number to attach the right side of the child to" -#: gtk/gtkmenu.c:667 +#: gtk/gtkmenu.c:689 msgid "Top Attach" msgstr "ঊৰ্ধ্ব সংযুক্তি" -#: gtk/gtkmenu.c:668 +#: gtk/gtkmenu.c:690 msgid "The row number to attach the top of the child to" msgstr "চাইল্ডৰ ওপৰতেৰ অংশে যি শাৰী নম্বৰ যুক্ত হ'ব" -#: gtk/gtkmenu.c:675 +#: gtk/gtkmenu.c:697 msgid "Bottom Attach" msgstr "নিম্ন সংযুক্তি" -#: gtk/gtkmenu.c:676 gtk/gtktable.c:195 +#: gtk/gtkmenu.c:698 gtk/gtktable.c:195 msgid "The row number to attach the bottom of the child to" msgstr "চাইল্ডৰ তলৰ অংশে যি শাৰী নম্বৰ যুক্ত হ'ব" -#: gtk/gtkmenu.c:690 +#: gtk/gtkmenu.c:712 msgid "Arbitrary constant to scale down the size of the scroll arrow" msgstr "Arbitrary constant to scale down the size of the scroll arrow" -#: gtk/gtkmenu.c:777 +#: gtk/gtkmenu.c:799 msgid "Can change accelerators" msgstr "চটপট কী (Key) পৰিবৰ্তন কৰতে পাৰে" -#: gtk/gtkmenu.c:778 +#: gtk/gtkmenu.c:800 msgid "" "Whether menu accelerators can be changed by pressing a key over the menu item" -msgstr "মেনু আইটেমেৰ ওপৰ চাপ দিয়ে চটপট কী (Key) পৰিবৰ্তন কৰা যাবে নে নাই" +msgstr "মেনু আইটেমেৰ ওপৰ চাপ দিয়ে চটপট কী (Key) পৰিবৰ্তন কৰা যাব নে নাই" -#: gtk/gtkmenu.c:783 +#: gtk/gtkmenu.c:805 msgid "Delay before submenus appear" msgstr "সাবমেনু দেখা যাওয়াৰ পূৰ্বে বিলম্ব" -#: gtk/gtkmenu.c:784 +#: gtk/gtkmenu.c:806 msgid "" "Minimum time the pointer must stay over a menu item before the submenu appear" msgstr "" -"সাবমেনু দেখা যাওয়াৰ পূৰ্বে সৰ্বনিম্ন যি সময় যাবত্‍ পয়েন্টাৰটি মেনুতে প্ৰদৰ্শিত সাবমেনুৰ " +"সাবমেনু দেখা যাওয়াৰ পূৰ্বে সৰ্বনিম্ন যি সময় যাবত্‍ পইন্টাৰটি মেনুতে প্ৰদৰ্শিত সাবমেনুৰ " "নামেৰ ওপৰ থাকবে" -#: gtk/gtkmenu.c:791 +#: gtk/gtkmenu.c:813 msgid "Delay before hiding a submenu" msgstr "সাবমেনু আড়াল কৰাৰ পূৰ্বে বিলম্ব" -#: gtk/gtkmenu.c:792 +#: gtk/gtkmenu.c:814 msgid "" "The time before hiding a submenu when the pointer is moving towards the " "submenu" -msgstr "পয়েন্টাৰ সাবমেনুৰ দিকে সৰে আসাৰ সময় সাবমেনুটি আড়াল কৰাৰ পূৰ্বে বিলম্ব" +msgstr "পইন্টাৰ সাবমেনুৰ দিকে সৰে আসাৰ সময় সাবমেনুটি আড়াল কৰাৰ পূৰ্বে বিলম্ব" #: gtk/gtkmenubar.c:168 msgid "Pack direction" @@ -3498,7 +3600,7 @@ msgstr "পেক তৰ দিক" #: gtk/gtkmenubar.c:169 msgid "The pack direction of the menubar" -msgstr "মেনুবাৰেৰ পেক তৰ দিক" +msgstr "মেনুবাৰৰ পেক তৰ দিক" #: gtk/gtkmenubar.c:185 msgid "Child Pack direction" @@ -3506,11 +3608,11 @@ msgstr "চাইল্ড পেক তৰ দিক" #: gtk/gtkmenubar.c:186 msgid "The child pack direction of the menubar" -msgstr "মেনুবাৰেৰ চাইল্ড পেক তৰ দিক" +msgstr "মেনুবাৰৰ চাইল্ড পেক তৰ দিক" #: gtk/gtkmenubar.c:195 msgid "Style of bevel around the menubar" -msgstr "মেনুবাৰেৰ চাৰদিকে বেভেলেৰ ধৰন" +msgstr "মেনুবাৰৰ চাৰদিকে বেভেলৰ ধৰন" #: gtk/gtkmenubar.c:202 gtk/gtktoolbar.c:590 msgid "Internal padding" @@ -3518,7 +3620,7 @@ msgstr "অভ্যন্তৰীণ পেডিং (Padding)" #: gtk/gtkmenubar.c:203 msgid "Amount of border space between the menubar shadow and the menu items" -msgstr "মেনুবাৰেৰ ছায়া আৰু মেনুবাৰেৰ সদস্যিৰ মাজত প্ৰান্তীয় স্থান" +msgstr "মেনুবাৰৰ ছায়া আৰু মেনুবাৰৰ সদস্যিৰ মাজত প্ৰান্তীয় স্থান" #: gtk/gtkmenubar.c:210 msgid "Delay before drop down menus appear" @@ -3528,47 +3630,47 @@ msgstr "ড্ৰপ ড্ৰাউন তালিকা দেখা দে msgid "Delay before the submenus of a menu bar appear" msgstr "মেনুবাৰৰ পৰা কোন সাবমেনু দেখা দেয়াৰ পূৰ্বে বিলম্ব" -#: gtk/gtkmenuitem.c:252 +#: gtk/gtkmenuitem.c:257 msgid "Right Justified" msgstr "Right Justified" -#: gtk/gtkmenuitem.c:253 +#: gtk/gtkmenuitem.c:258 msgid "" "Sets whether the menu item appears justified at the right side of a menu bar" msgstr "" "Sets whether the menu item appears justified at the right side of a menu bar" -#: gtk/gtkmenuitem.c:267 +#: gtk/gtkmenuitem.c:272 msgid "Submenu" msgstr "Submenu" -#: gtk/gtkmenuitem.c:268 +#: gtk/gtkmenuitem.c:273 msgid "The submenu attached to the menu item, or NULL if it has none" msgstr "The submenu attached to the menu item, or NULL if it has none" -#: gtk/gtkmenuitem.c:286 +#: gtk/gtkmenuitem.c:291 msgid "Sets the accelerator path of the menu item" msgstr "Sets the accelerator path of the menu item" # -#: gtk/gtkmenuitem.c:301 +#: gtk/gtkmenuitem.c:306 msgid "The text for the child label" -msgstr "লেবেলেৰ টেক্সট" +msgstr "লেবেলৰ টেক্সট" # -#: gtk/gtkmenuitem.c:364 +#: gtk/gtkmenuitem.c:369 msgid "Amount of space used up by arrow, relative to the menu item's font size" msgstr "সৰ্বমোট" # -#: gtk/gtkmenuitem.c:377 +#: gtk/gtkmenuitem.c:382 msgid "Width in Characters" msgstr "অক্ষৰ হিচাপে প্ৰস্থ" # -#: gtk/gtkmenuitem.c:378 +#: gtk/gtkmenuitem.c:383 msgid "The minimum desired width of the menu item in characters" -msgstr "অক্ষৰ হিচাপে লেবেলেৰ আকাঙ্খিত প্ৰস্থ" +msgstr "অক্ষৰ হিচাপে লেবেলৰ আকাঙ্খিত প্ৰস্থ" #: gtk/gtkmenushell.c:374 msgid "Take Focus" @@ -3576,7 +3678,7 @@ msgstr "ফোকাস নাও" #: gtk/gtkmenushell.c:375 msgid "A boolean that determines whether the menu grabs the keyboard focus" -msgstr "এটা বুলিয়ান মান যা নিৰ্দেশ কৰে যি মেনুটি কীবোৰ্ডেৰ ফ'কাচ নেয় নে নাই" +msgstr "এটা বুলিয়ান মান যাৰ নিৰ্দেশ কৰি যি মেনুটি কীবোৰ্ডেৰ ফ'কাচ নেয় নে নাই" #: gtk/gtkmenutoolbutton.c:245 gtk/gtkoptionmenu.c:161 msgid "Menu" @@ -3592,7 +3694,7 @@ msgstr "ছবি/লেবেল ইয়াৰ প্ৰান্ত" #: gtk/gtkmessagedialog.c:99 msgid "Width of border around the label and image in the message dialog" -msgstr "মেসেজ ডায়ালগে লেবেল আৰু ছবিৰ চাৰপাশস্থ প্ৰান্তেৰ প্ৰস্থ " +msgstr "মেসেজ ডায়ালগে লেবেল আৰু ছবিৰ চাৰপাশস্থ প্ৰান্তৰ প্ৰস্থ " #: gtk/gtkmessagedialog.c:114 msgid "Use separator" @@ -3603,14 +3705,6 @@ msgid "" "Whether to put a separator between the message dialog's text and the buttons" msgstr "ডায়ালগেৰ টেক্সট আৰু বুটামৰ মধ্যবৰ্তী স্থানে কোন বিভাজক ব্যৱহাৰ কৰা হ'ব নে নাই" -#: gtk/gtkmessagedialog.c:128 -msgid "Message Type" -msgstr "বাৰ্তাৰ ধৰন" - -#: gtk/gtkmessagedialog.c:129 -msgid "The type of message" -msgstr "বাৰ্তাৰ ধৰন" - #: gtk/gtkmessagedialog.c:136 msgid "Message Buttons" msgstr "মেসেজ বুটাম" @@ -3678,26 +3772,26 @@ msgid "" msgstr "উইজেটেৰ ওপৰত আৰু নীচে যত পিক্সেল ৰিক্ত স্থান যোগ কৰা হ'ব" # -#: gtk/gtkmountoperation.c:139 +#: gtk/gtkmountoperation.c:160 msgid "Parent" msgstr "পেৰেন্ট" # -#: gtk/gtkmountoperation.c:140 +#: gtk/gtkmountoperation.c:161 msgid "The parent window" msgstr "উইন্ডোৰ ধৰন " # -#: gtk/gtkmountoperation.c:147 +#: gtk/gtkmountoperation.c:168 msgid "Is Showing" msgstr "শিৰোনাম প্ৰদৰ্শন কৰো" -#: gtk/gtkmountoperation.c:148 +#: gtk/gtkmountoperation.c:169 msgid "Are we showing a dialog" msgstr "Are we showing a dialog" # -#: gtk/gtkmountoperation.c:156 +#: gtk/gtkmountoperation.c:177 msgid "The screen where this window will be displayed." msgstr "এই উইন্ডোটি যি পৰ্দ্দায় প্ৰদৰ্শিত হ'ব" @@ -3711,35 +3805,35 @@ msgstr "বৰ্তমান পাতাৰ সূচী" #: gtk/gtknotebook.c:586 msgid "Tab Position" -msgstr "ট্যাবেৰ অবস্থান" +msgstr "ট্যাবৰ অবস্থান" #: gtk/gtknotebook.c:587 msgid "Which side of the notebook holds the tabs" -msgstr "নোট বইয়েৰ কোন দিকটি ট্যাব ধাৰণ কৰে" +msgstr "নোট বইয়েৰ কোন দিকটি ট্যাব ধাৰণ কৰি" #: gtk/gtknotebook.c:594 msgid "Tab Border" -msgstr "ট্যাবেৰ প্ৰান্ত" +msgstr "ট্যাবৰ প্ৰান্ত" #: gtk/gtknotebook.c:595 msgid "Width of the border around the tab labels" -msgstr "ট্যাব লেবেলেৰ প্ৰান্তেৰ প্ৰস্থ" +msgstr "ট্যাব লেবেলৰ প্ৰান্তৰ প্ৰস্থ" #: gtk/gtknotebook.c:603 msgid "Horizontal Tab Border" -msgstr "ট্যাবেৰ পথালি প্ৰান্ত" +msgstr "ট্যাবৰ পথালি প্ৰান্ত" #: gtk/gtknotebook.c:604 msgid "Width of the horizontal border of tab labels" -msgstr "ট্যাব লেবেলেৰ পথালি প্ৰান্তেৰ প্ৰস্থ" +msgstr "ট্যাব লেবেলৰ পথালি প্ৰান্তৰ প্ৰস্থ" #: gtk/gtknotebook.c:612 msgid "Vertical Tab Border" -msgstr "ট্যাবেৰ উলম্ব প্ৰান্ত" +msgstr "ট্যাবৰ উলম্ব প্ৰান্ত" #: gtk/gtknotebook.c:613 msgid "Width of the vertical border of tab labels" -msgstr "ট্যাব লেবেলেৰ উলম্ব প্ৰান্তেৰ প্ৰস্থ" +msgstr "ট্যাব লেবেলৰ উলম্ব প্ৰান্তৰ প্ৰস্থ" #: gtk/gtknotebook.c:621 msgid "Show Tabs" @@ -3764,7 +3858,7 @@ msgstr "স্ক্ৰল কৰাৰ যোগ্য" #: gtk/gtknotebook.c:636 msgid "If TRUE, scroll arrows are added if there are too many tabs to fit" msgstr "" -"ইয়াৰ মান সত্য (TRUE) হলে, ট্যাবেৰ সংখ্যা যদি অত্যধিক হয় তেন্তে স্ক্ৰলযোগ্য তীৰচিহ্ন " +"ইয়াৰ মান সত্য (TRUE) হলে, ট্যাবৰ সংখ্যা যদি অত্যধিক হয় তেন্তে স্ক্ৰলযোগ্য তীৰচিহ্ন " "যোগ কৰা হ'ব" #: gtk/gtknotebook.c:642 @@ -3776,12 +3870,12 @@ msgid "" "If TRUE, pressing the right mouse button on the notebook pops up a menu that " "you can use to go to a page" msgstr "" -"যদি TRUE হয় তেন্তে নোটবইয়ে মাউসেৰ ডান বুটাম চাপলে এটা তালিকা দেখা যাবে যিখানৰ " -"পৰা অন্যান্য পৃষ্ঠায় যাওয়া যাবে" +"যদি TRUE হয় তেন্তে নোটবইয়ে মাউছৰ ডান বুটাম চাপলে এটা তালিকা দেখা যাব যিখানৰ " +"পৰা অন্যান্য পৃষ্ঠায় যাওয়া যাব" #: gtk/gtknotebook.c:650 msgid "Whether tabs should have homogeneous sizes" -msgstr "সকল ট্যাবেৰ আকাৰ একই হ'ব নে নাই" +msgstr "সকল ট্যাবৰ আকাৰ একই হ'ব নে নাই" #: gtk/gtknotebook.c:656 msgid "Group ID" @@ -3802,7 +3896,7 @@ msgstr "দল উল্লিখিত সময় অবধি" #: gtk/gtknotebook.c:680 msgid "Tab label" -msgstr "ট্যাবেৰ লেবেল" +msgstr "ট্যাবৰ লেবেল" #: gtk/gtknotebook.c:681 msgid "The string displayed on the child's tab label" @@ -3830,7 +3924,7 @@ msgstr "ট্যাব পূৰণ" #: gtk/gtknotebook.c:709 msgid "Whether the child's tab should fill the allocated area or not" -msgstr "চাইল্ডৰ ট্যাব বৰাদ্দকৃত ক্ষেত্ৰ পূৰণ কৰবে নে নাই" +msgstr "চাইল্ডৰ ট্যাব বৰাদ্দকৃত ক্ষেত্ৰ পূৰণ কৰিব নে নাই" #: gtk/gtknotebook.c:715 msgid "Tab pack type" @@ -3860,7 +3954,7 @@ msgstr "পশ্চাত্‍গামী গৌণ স্টেপাৰ" msgid "" "Display a second backward arrow button on the opposite end of the tab area" msgstr "" -"ট্যাব অংশেৰ বিপৰীত প্ৰান্তে এটা পশ্চাত্‍গামী গৌণ স্টেপাৰ তীৰচিহ্নধাৰী বুটাম প্ৰদৰ্শন কৰো" +"ট্যাব অংশৰ বিপৰীত প্ৰান্তে এটা পশ্চাত্‍গামী গৌণ স্টেপাৰ তীৰচিহ্নধাৰী বুটাম প্ৰদৰ্শন কৰো" #: gtk/gtknotebook.c:761 gtk/gtkscrollbar.c:88 msgid "Secondary forward stepper" @@ -3870,7 +3964,7 @@ msgstr "সম্মুখগামী গৌণ স্টেপাৰ" msgid "" "Display a second forward arrow button on the opposite end of the tab area" msgstr "" -"ট্যাব অংশেৰ বিপৰীত প্ৰান্তে এটা সম্মুখগামী গৌণ স্টেপাৰ তীৰচিহ্নধাৰী বুটাম প্ৰদৰ্শন কৰো" +"ট্যাব অংশৰ বিপৰীত প্ৰান্তে এটা সম্মুখগামী গৌণ স্টেপাৰ তীৰচিহ্নধাৰী বুটাম প্ৰদৰ্শন কৰো" #: gtk/gtknotebook.c:776 gtk/gtkscrollbar.c:67 msgid "Backward stepper" @@ -3954,11 +4048,11 @@ msgstr "অবস্থানেৰ বৈশিষ্ট্য ব্যৱহ #: gtk/gtkpaned.c:258 msgid "Handle Size" -msgstr "হাতলেৰ (Handle) আকাৰ" +msgstr "হাতলৰ (Handle) আকাৰ" #: gtk/gtkpaned.c:259 msgid "Width of handle" -msgstr "হাতলেৰ প্ৰস্থ" +msgstr "হাতলৰ প্ৰস্থ" #: gtk/gtkpaned.c:275 msgid "Minimal Position" @@ -3996,9 +4090,9 @@ msgstr "" "ইয়াৰ মান সত্য হলে (TRUE), চাইল্ড উইজেটেৰ আকাৰ ইয়াৰ প্ৰয়োজন অপেক্ষা ক্ষুদ্ৰতৰ কৰা যায়" # -#: gtk/gtkplug.c:150 gtk/gtkstatusicon.c:309 +#: gtk/gtkplug.c:150 gtk/gtkstatusicon.c:312 msgid "Embedded" -msgstr "এমবেড করা" +msgstr "এমবেড কৰা" #: gtk/gtkplug.c:151 msgid "Whether or not the plug is embedded" @@ -4134,11 +4228,11 @@ msgstr "ন্যাট মানসমূহ" msgid "Printer settings" msgstr "মুদ্ৰক ছেটিংছ..." -#: gtk/gtkprintjob.c:143 gtk/gtkprintjob.c:144 gtk/gtkprintunixdialog.c:266 +#: gtk/gtkprintjob.c:143 gtk/gtkprintjob.c:144 gtk/gtkprintunixdialog.c:302 msgid "Page Setup" msgstr "পৃষ্ঠাৰ বিন্যাস" -#: gtk/gtkprintjob.c:152 gtk/gtkprintoperation.c:1056 +#: gtk/gtkprintjob.c:152 gtk/gtkprintoperation.c:1082 msgid "Track Print Status" msgstr "প্ৰিন্ট কৰক অবস্থা" @@ -4148,162 +4242,177 @@ msgid "" "print data has been sent to the printer or print server." msgstr "পৰে." -#: gtk/gtkprintoperation.c:928 +#: gtk/gtkprintoperation.c:954 msgid "Default Page Setup" msgstr "অবিকল্পিত পৃষ্ঠা" -#: gtk/gtkprintoperation.c:929 +#: gtk/gtkprintoperation.c:955 msgid "The GtkPageSetup used by default" msgstr "The GtkPageSetup used by default" -#: gtk/gtkprintoperation.c:947 gtk/gtkprintunixdialog.c:284 +#: gtk/gtkprintoperation.c:973 gtk/gtkprintunixdialog.c:320 msgid "Print Settings" msgstr "প্ৰিন্ট কৰক" -#: gtk/gtkprintoperation.c:948 gtk/gtkprintunixdialog.c:285 +#: gtk/gtkprintoperation.c:974 gtk/gtkprintunixdialog.c:321 msgid "The GtkPrintSettings used for initializing the dialog" msgstr "উল্লিখিত সময় অবধি" -#: gtk/gtkprintoperation.c:966 +#: gtk/gtkprintoperation.c:992 msgid "Job Name" msgstr "নাম" -#: gtk/gtkprintoperation.c:967 +#: gtk/gtkprintoperation.c:993 msgid "A string used for identifying the print job." msgstr "উল্লিখিত সময় অবধি." -#: gtk/gtkprintoperation.c:991 +#: gtk/gtkprintoperation.c:1017 msgid "Number of Pages" msgstr "সৰ্বমোট" -#: gtk/gtkprintoperation.c:992 +#: gtk/gtkprintoperation.c:1018 msgid "The number of pages in the document." msgstr "সৰ্বমোট." -#: gtk/gtkprintoperation.c:1013 gtk/gtkprintunixdialog.c:274 +#: gtk/gtkprintoperation.c:1039 gtk/gtkprintunixdialog.c:310 msgid "Current Page" msgstr "পৃষ্ঠা" -#: gtk/gtkprintoperation.c:1014 gtk/gtkprintunixdialog.c:275 +#: gtk/gtkprintoperation.c:1040 gtk/gtkprintunixdialog.c:311 msgid "The current page in the document" msgstr "The current page in the document" -#: gtk/gtkprintoperation.c:1035 +#: gtk/gtkprintoperation.c:1061 msgid "Use full page" msgstr "Use full page" -#: gtk/gtkprintoperation.c:1036 +#: gtk/gtkprintoperation.c:1062 msgid "" "TRUE if the origin of the context should be at the corner of the page and " "not the corner of the imageable area" msgstr "সৰ্বমোট সৰ্বমোট সৰ্বমোট" -#: gtk/gtkprintoperation.c:1057 +#: gtk/gtkprintoperation.c:1083 msgid "" "TRUE if the print operation will continue to report on the print job status " "after the print data has been sent to the printer or print server." msgstr "সক্ৰিয় পৰে." -#: gtk/gtkprintoperation.c:1074 +#: gtk/gtkprintoperation.c:1100 msgid "Unit" msgstr "একক" -#: gtk/gtkprintoperation.c:1075 +#: gtk/gtkprintoperation.c:1101 msgid "The unit in which distances can be measured in the context" msgstr "The unit in which distances can be measured in the context" -#: gtk/gtkprintoperation.c:1092 +#: gtk/gtkprintoperation.c:1118 msgid "Show Dialog" msgstr "ডায়ালগ" -#: gtk/gtkprintoperation.c:1093 +#: gtk/gtkprintoperation.c:1119 msgid "TRUE if a progress dialog is shown while printing." msgstr "হলো." -#: gtk/gtkprintoperation.c:1116 +#: gtk/gtkprintoperation.c:1142 msgid "Allow Async" msgstr "Allow Async" -#: gtk/gtkprintoperation.c:1117 +#: gtk/gtkprintoperation.c:1143 msgid "TRUE if print process may run asynchronous." msgstr "TRUE if print process may run asynchronous." -#: gtk/gtkprintoperation.c:1139 gtk/gtkprintoperation.c:1140 +#: gtk/gtkprintoperation.c:1165 gtk/gtkprintoperation.c:1166 msgid "Export filename" msgstr "Export filename" -#: gtk/gtkprintoperation.c:1154 +#: gtk/gtkprintoperation.c:1180 msgid "Status" msgstr "অবস্থা" -#: gtk/gtkprintoperation.c:1155 +#: gtk/gtkprintoperation.c:1181 msgid "The status of the print operation" msgstr "সৰ্বমোট" -#: gtk/gtkprintoperation.c:1175 +#: gtk/gtkprintoperation.c:1201 msgid "Status String" msgstr "অবস্থা বাক্য" -#: gtk/gtkprintoperation.c:1176 +#: gtk/gtkprintoperation.c:1202 msgid "A human-readable description of the status" msgstr "বিবৰণ সৰ্বমোট" -#: gtk/gtkprintoperation.c:1194 +#: gtk/gtkprintoperation.c:1220 msgid "Custom tab label" msgstr "নিজস্ব" -#: gtk/gtkprintoperation.c:1195 +#: gtk/gtkprintoperation.c:1221 msgid "Label for the tab containing custom widgets." msgstr "Label উল্লিখিত সময় অবধি স্বনিৰ্বাচিত." -# -#: gtk/gtkprintoperation.c:1210 gtk/gtkprintunixdialog.c:309 -#, fuzzy +#: gtk/gtkprintoperation.c:1236 gtk/gtkprintunixdialog.c:345 msgid "Support Selection" -msgstr "রং নির্বাচন" +msgstr "নিৰ্বাচনৰ সমৰ্থন কৰক" -#: gtk/gtkprintoperation.c:1211 +#: gtk/gtkprintoperation.c:1237 msgid "TRUE if the print operation will support print of selection." -msgstr "" +msgstr "TRUE যদি মূদ্ৰণ কাৰ্য্যই নিৰ্বাচনৰ মূদ্ৰণৰ সমৰ্থন কৰিব ।" -#: gtk/gtkprintoperation.c:1227 gtk/gtkprintunixdialog.c:317 -#, fuzzy +#: gtk/gtkprintoperation.c:1253 gtk/gtkprintunixdialog.c:353 msgid "Has Selection" -msgstr "Has selection" +msgstr "নিৰ্বাচন আছে" -#: gtk/gtkprintoperation.c:1228 +#: gtk/gtkprintoperation.c:1254 msgid "TRUE if a selecion exists." -msgstr "" +msgstr "TRUE যদি এটা নিৰ্বাচন আছে ।" -#: gtk/gtkprintunixdialog.c:267 +#: gtk/gtkprintoperation.c:1269 gtk/gtkprintunixdialog.c:361 +msgid "Embed Page Setup" +msgstr "পৃষ্ঠাৰ বিন্যাস প্ৰোথিত কৰক" + +#: gtk/gtkprintoperation.c:1270 +msgid "TRUE if page setup combos are embedded in GtkPrintDialog" +msgstr "TRUE যদি পৃষ্ঠাৰ বিন্যাসৰ কম্বো GtkPrintDialog ত প্ৰোথিত হৈছে" + +#: gtk/gtkprintoperation.c:1291 +msgid "Number of Pages To Print" +msgstr "মূদ্ৰণ কৰিব লগা সৰ্বমুঠ পৃষ্ঠা" + +#: gtk/gtkprintoperation.c:1292 +msgid "The number of pages that will be printed." +msgstr "মূদ্ৰণ হোৱা সৰ্বমুঠ পৃষ্ঠাৰ সংখ্যা ।" + +#: gtk/gtkprintunixdialog.c:303 msgid "The GtkPageSetup to use" msgstr "The GtkPageSetup to use" -#: gtk/gtkprintunixdialog.c:292 +#: gtk/gtkprintunixdialog.c:328 msgid "Selected Printer" msgstr "Selected" -#: gtk/gtkprintunixdialog.c:293 +#: gtk/gtkprintunixdialog.c:329 msgid "The GtkPrinter which is selected" msgstr "হলো" -#: gtk/gtkprintunixdialog.c:300 +#: gtk/gtkprintunixdialog.c:336 msgid "Manual Capabilites" -msgstr "" +msgstr "হস্তচালিত গুণ" -#: gtk/gtkprintunixdialog.c:301 +#: gtk/gtkprintunixdialog.c:337 msgid "Capabilities the application can handle" -msgstr "" +msgstr "অনুপ্ৰয়োগে পৰিচালন কৰিব পৰা ক্ষমতা" -#: gtk/gtkprintunixdialog.c:310 -#, fuzzy +#: gtk/gtkprintunixdialog.c:346 msgid "Whether the dialog supports selection" -msgstr "নিৰ্বাচিত ফন্টৰ সাহায্যি লেবেলে লেখা হ'ব নে নাই" +msgstr "সম্বাদে নিৰ্বাচনৰ সমৰ্থন কৰে নে নাই" -#: gtk/gtkprintunixdialog.c:318 -#, fuzzy +#: gtk/gtkprintunixdialog.c:354 msgid "Whether the application has a selection" -msgstr "কামটো সক্ৰিয় হয় নে নহয়" +msgstr "অনুপ্ৰয়োগত নিৰ্বাচন আছে নে নাই" + +#: gtk/gtkprintunixdialog.c:362 +msgid "TRUE if page setup combos are embedded in GtkPrintUnixDialog" +msgstr "TRUE যদি পৃষ্ঠা প্ৰতিষ্ঠাৰ কম্বোক GtkPrintUnixDialog ত প্ৰোথিত কৰা হৈছে" #: gtk/gtkprogress.c:102 msgid "Activity mode" @@ -4326,11 +4435,11 @@ msgstr "হলো." #: gtk/gtkprogressbar.c:119 msgid "The GtkAdjustment connected to the progress bar (Deprecated)" -msgstr "প্ৰগ্ৰেছ বাৰেৰ সৈতে যুক্ত GtkAdjustment (অনুমোদিত নয়)" +msgstr "প্ৰগ্ৰেছ বাৰৰ সৈতে যুক্ত GtkAdjustment (অনুমোদিত নয়)" #: gtk/gtkprogressbar.c:135 msgid "Bar style" -msgstr "বাৰেৰ ধৰন" +msgstr "বাৰৰ ধৰন" #: gtk/gtkprogressbar.c:136 msgid "Specifies the visual style of the bar in percentage mode (Deprecated)" @@ -4371,7 +4480,7 @@ msgstr "ভগ্নাংশ" #: gtk/gtkprogressbar.c:169 msgid "The fraction of total work that has been completed" -msgstr "পুৰো কাজটাৰ যি ভগ্নাংশ সম্পূৰ্ণ হৈছে" +msgstr "পুৰো কামটাৰ যি ভগ্নাংশ সম্পূৰ্ণ হৈছে" #: gtk/gtkprogressbar.c:176 msgid "Pulse Step" @@ -4380,8 +4489,7 @@ msgstr "স্পন্দন ধাপ" #: gtk/gtkprogressbar.c:177 msgid "The fraction of total progress to move the bouncing block when pulsed" msgstr "" -"মোট কামৰ যি ভগাংশ পৰিমাণ সম্পন্ন হলে স্পন্দনেৰ ফলে লাফাতে থাকা ব্লকটিকে সৰানো " -"যাবে " +"মোট কামৰ যি ভগাংশ পৰিমাণ সম্পন্ন হলে স্পন্দনেৰ ফলে লাফাতে থাকা ব্লকটিকে সৰানো যাব " #: gtk/gtkprogressbar.c:185 msgid "Text to be displayed in the progress bar" @@ -4420,7 +4528,7 @@ msgstr "পথালি বিভাজকেৰ প্ৰস্থ" # #: gtk/gtkprogressbar.c:235 msgid "The minimum horizontal width of the progress bar" -msgstr "লেবেলেৰ পথালি সংৰেখন" +msgstr "লেবেলৰ পথালি সংৰেখন" # #: gtk/gtkprogressbar.c:247 @@ -4430,7 +4538,7 @@ msgstr "পথালি সংৰেখন" # #: gtk/gtkprogressbar.c:248 msgid "Minimum horizontal height of the progress bar" -msgstr "প্ৰগ্ৰেছবাৰেৰ মান" +msgstr "প্ৰগ্ৰেছবাৰৰ মান" # #: gtk/gtkprogressbar.c:260 @@ -4450,7 +4558,7 @@ msgstr "চাইল্ডৰ সৰ্বনিম্ন উচ্চতা" # #: gtk/gtkprogressbar.c:274 msgid "The minimum vertical height of the progress bar" -msgstr "প্ৰগ্ৰেছবাৰেৰ মান" +msgstr "প্ৰগ্ৰেছবাৰৰ মান" #: gtk/gtkradioaction.c:111 msgid "The value" @@ -4501,7 +4609,7 @@ msgstr "পৰ্দ্দায় যিভাবে সীমাটি আপগ #: gtk/gtkrange.c:368 msgid "The GtkAdjustment that contains the current value of this range object" -msgstr "যি GtkAdjustment এই সীমাসূচক অবজেক্টেৰ বৰ্তমান মান ধাৰণ কৰে" +msgstr "যি GtkAdjustment এই সীমাসূচক অবজেক্টেৰ বৰ্তমান মান ধাৰণ কৰি" #: gtk/gtkrange.c:375 msgid "Inverted" @@ -4557,7 +4665,7 @@ msgstr "The fill level." #: gtk/gtkrange.c:452 msgid "Slider Width" -msgstr "স্লাইডাৰেৰ প্ৰস্থ" +msgstr "স্লাইডাৰৰ প্ৰস্থ" #: gtk/gtkrange.c:453 msgid "Width of scrollbar or scale thumb" @@ -4569,12 +4677,11 @@ msgstr "দীৰ্ঘ বক্সৰ প্ৰান্ত" #: gtk/gtkrange.c:461 msgid "Spacing between thumb/steppers and outer trough bevel" -msgstr "" -"থাম্ব/স্টেপাৰ এবং বহিঃস্থ দীৰ্ঘ বক্সৰ ন্যায় বেভেলেৰ মধ্যবৰ্তী ৰিক্ত স্থানৰ পৰিমাণ" +msgstr "থাম্ব/স্টেপাৰ এবং বহিঃস্থ দীৰ্ঘ বক্সৰ ন্যায় বেভেলৰ মধ্যবৰ্তী ৰিক্ত স্থানৰ পৰিমাণ" #: gtk/gtkrange.c:468 msgid "Stepper Size" -msgstr "স্টেপাৰেৰ আকাৰ" +msgstr "স্টেপাৰৰ আকাৰ" #: gtk/gtkrange.c:469 msgid "Length of step buttons at ends" @@ -4787,7 +4894,7 @@ msgstr "আঁকাৰ মান" #: gtk/gtkscale.c:229 msgid "Whether the current value is displayed as a string next to the slider" -msgstr "স্লাইডাৰেৰ পাশে বৰ্তমান মানটিকে পংক্তি হিচাপে প্ৰদৰ্শন কৰা হ'ব নে নাই" +msgstr "স্লাইডাৰৰ পাশে বৰ্তমান মানটিকে পংক্তি হিচাপে প্ৰদৰ্শন কৰা হ'ব নে নাই" #: gtk/gtkscale.c:236 msgid "Value Position" @@ -4799,11 +4906,11 @@ msgstr "যি অবস্থানে বৰ্তমান মানটি #: gtk/gtkscale.c:244 msgid "Slider Length" -msgstr "স্লাইডাৰেৰ দৈৰ্ঘ্য" +msgstr "স্লাইডাৰৰ দৈৰ্ঘ্য" #: gtk/gtkscale.c:245 msgid "Length of scale's slider" -msgstr "মাপদন্ডেৰ স্লাইডাৰেৰ দৈৰ্ঘ্য" +msgstr "মাপদন্ডেৰ স্লাইডাৰৰ দৈৰ্ঘ্য" #: gtk/gtkscale.c:253 msgid "Value spacing" @@ -4811,7 +4918,7 @@ msgstr "স্পেসিং তৰ মান" #: gtk/gtkscale.c:254 msgid "Space between value text and the slider/trough area" -msgstr "মানসূচক টেক্সট আৰু স্লাইডাৰ/থ্ৰু অংশেৰ মধ্যবৰ্তী স্থান তৰ সংখ্যা" +msgstr "মানসূচক টেক্সট আৰু স্লাইডাৰ/থ্ৰু অংশৰ মধ্যবৰ্তী স্থান তৰ সংখ্যা" #: gtk/gtkscalebutton.c:207 msgid "The value of the scale" @@ -4824,7 +4931,7 @@ msgstr "The icon size" #: gtk/gtkscalebutton.c:226 msgid "" "The GtkAdjustment that contains the current value of this scale button object" -msgstr "ধাৰন কৰে সৰ্বমোট" +msgstr "ধাৰন কৰি সৰ্বমোট" # #: gtk/gtkscalebutton.c:254 @@ -4837,41 +4944,41 @@ msgstr "তালিকা সৰ্বমোট" #: gtk/gtkscrollbar.c:51 msgid "Minimum Slider Length" -msgstr "স্লাইডাৰেৰ সৰ্বনিম্ন দৈৰ্ঘ্য" +msgstr "স্লাইডাৰৰ সৰ্বনিম্ন দৈৰ্ঘ্য" #: gtk/gtkscrollbar.c:52 msgid "Minimum length of scrollbar slider" -msgstr "স্ক্ৰলবাৰ স্লাইডাৰেৰ সৰ্বনিম্ন দৈৰ্ঘ্য" +msgstr "স্ক্ৰলবাৰ স্লাইডাৰৰ সৰ্বনিম্ন দৈৰ্ঘ্য" #: gtk/gtkscrollbar.c:60 msgid "Fixed slider size" -msgstr "স্লাইডাৰেৰ পূৰ্বনিৰ্দিষ্ট দৈৰ্ঘ্য" +msgstr "স্লাইডাৰৰ পূৰ্বনিৰ্দিষ্ট দৈৰ্ঘ্য" #: gtk/gtkscrollbar.c:61 msgid "Don't change slider size, just lock it to the minimum length" -msgstr "স্লাইডাৰেৰ দৈৰ্ঘ্য পৰিবৰ্তন না কৰে সৰ্বনিম্ন দৈৰ্ঘ্যি স্থিৰ ৰাখা হোক" +msgstr "স্লাইডাৰৰ দৈৰ্ঘ্য পৰিবৰ্তন না কৰি সৰ্বনিম্ন দৈৰ্ঘ্যি স্থিৰ ৰাখা হোক" #: gtk/gtkscrollbar.c:82 msgid "" "Display a second backward arrow button on the opposite end of the scrollbar" -msgstr "স্ক্ৰলবাৰেৰ বিপৰীত প্ৰান্তে এটা পশ্চাত্‍গামী তীৰচিহ্নধাৰী বুটাম প্ৰদৰ্শন কৰো" +msgstr "স্ক্ৰলবাৰৰ বিপৰীত প্ৰান্তে এটা পশ্চাত্‍গামী তীৰচিহ্নধাৰী বুটাম প্ৰদৰ্শন কৰো" #: gtk/gtkscrollbar.c:89 msgid "" "Display a second forward arrow button on the opposite end of the scrollbar" msgstr "প্ৰদৰ্শন দ্বিতীয় সক্ৰিয় সৰ্বমোট" -#: gtk/gtkscrolledwindow.c:218 gtk/gtktext.c:545 gtk/gtktreeview.c:578 +#: gtk/gtkscrolledwindow.c:218 gtk/gtktext.c:545 gtk/gtktreeview.c:569 msgid "Horizontal Adjustment" msgstr "পথালি সমন্বয়" -#: gtk/gtkscrolledwindow.c:225 gtk/gtktext.c:553 gtk/gtktreeview.c:586 +#: gtk/gtkscrolledwindow.c:225 gtk/gtktext.c:553 gtk/gtktreeview.c:577 msgid "Vertical Adjustment" msgstr "উলম্ব সমন্বয়" #: gtk/gtkscrolledwindow.c:232 msgid "Horizontal Scrollbar Policy" -msgstr "পথালি স্ক্ৰলবাৰেৰ নীতি" +msgstr "পথালি স্ক্ৰলবাৰৰ নীতি" #: gtk/gtkscrolledwindow.c:233 msgid "When the horizontal scrollbar is displayed" @@ -4879,7 +4986,7 @@ msgstr "যখন পথালি স্ক্ৰলবাৰ প্ৰদৰ্ #: gtk/gtkscrolledwindow.c:240 msgid "Vertical Scrollbar Policy" -msgstr "উলম্ব স্ক্ৰলবাৰেৰ নীতি" +msgstr "উলম্ব স্ক্ৰলবাৰৰ নীতি" #: gtk/gtkscrolledwindow.c:241 msgid "When the vertical scrollbar is displayed" @@ -4911,7 +5018,7 @@ msgstr "ছায়াৰ ধৰন" #: gtk/gtkscrolledwindow.c:275 msgid "Style of bevel around the contents" -msgstr "অভ্যন্তৰস্থ বস্তুৰ (Content) চাৰপাশে অবস্থিত বেভেলেৰ ধৰন" +msgstr "অভ্যন্তৰস্থ বস্তুৰ (Content) চাৰপাশে অবস্থিত বেভেলৰ ধৰন" #: gtk/gtkscrolledwindow.c:289 msgid "Scrollbars within bevel" @@ -4927,7 +5034,7 @@ msgstr "স্ক্ৰলবাৰে ৰিক্ত স্থানৰ সং #: gtk/gtkscrolledwindow.c:297 msgid "Number of pixels between the scrollbars and the scrolled window" -msgstr "স্ক্ৰলবাৰ এবং স্ক্ৰলবাৰেৰ সৈতে সংযুক্ত উইন্ডোৰ মধ্যবৰ্তী পিক্ছেলৰসংখ্যা" +msgstr "স্ক্ৰলবাৰ এবং স্ক্ৰলবাৰৰ সৈতে সংযুক্ত উইন্ডোৰ মধ্যবৰ্তী পিক্ছেলৰসংখ্যা" #: gtk/gtkscrolledwindow.c:312 msgid "Scrolled Window Placement" @@ -4973,19 +5080,19 @@ msgstr "" #: gtk/gtksettings.c:240 msgid "Cursor Blink" -msgstr "কাৰ্সাৰেৰ ঝলকানি" +msgstr "কাৰ্ছাৰৰ " #: gtk/gtksettings.c:241 msgid "Whether the cursor should blink" -msgstr "কাৰ্সাৰ ঝলকানো হ'ব কি না" +msgstr "কাৰ্ছাৰ ঝলকানো হ'ব কি না" #: gtk/gtksettings.c:248 msgid "Cursor Blink Time" -msgstr "কাৰ্সাৰ ঝলকানিৰ সময়" +msgstr "কাৰ্ছাৰ ৰ সময়" #: gtk/gtksettings.c:249 msgid "Length of the cursor blink cycle, in milliseconds" -msgstr "কাৰ্সাৰ ঝলকানিৰ সময়কালেৰ দৈৰ্ঘ্য, মিলিসেকেন্ডে ব্যক্ত " +msgstr "কাৰ্ছাৰ ৰ সময়কালৰ দৈৰ্ঘ্য, মিলিসেকেন্ডে ব্যক্ত " #: gtk/gtksettings.c:268 msgid "Cursor Blink Timeout" @@ -4997,14 +5104,14 @@ msgstr "সময় পৰে সেকেন্ড" #: gtk/gtksettings.c:276 msgid "Split Cursor" -msgstr "বিভক্ত কাৰ্সাৰ" +msgstr "বিভক্ত কাৰ্ছাৰ" #: gtk/gtksettings.c:277 msgid "" "Whether two cursors should be displayed for mixed left-to-right and right-to-" "left text" msgstr "" -"বাম-থেকে-ডান এবং ডান-থেকে-বাম এধৰনেৰ টেক্সটৰ মিশ্ৰণ প্ৰদৰ্শনেৰ সময় দুটি কাৰ্সাৰ " +"বাম-থেকে-ডান এবং ডান-থেকে-বাম এধৰনেৰ টেক্সটৰ মিশ্ৰণ প্ৰদৰ্শনেৰ সময় দুটি কাৰ্ছাৰ " "ব্যৱহাৰ কৰা হ'ব নে নাই" #: gtk/gtksettings.c:284 @@ -5041,11 +5148,11 @@ msgstr "যি মূল থিম আৰসি ফাইল লোড কৰা #: gtk/gtksettings.c:320 msgid "Menu bar accelerator" -msgstr "মেনু বাৰেৰ চটপট কী (Key)" +msgstr "মেনু বাৰৰ চটপট কী (Key)" #: gtk/gtksettings.c:321 msgid "Keybinding to activate the menu bar" -msgstr "যি সকল কী (Key) সমষ্টি মেনুবাৰকে সক্ৰিয় কৰে" +msgstr "যি সকল কী (Key) সমষ্টি মেনুবাৰকে সক্ৰিয় কৰি" #: gtk/gtksettings.c:329 msgid "Drag threshold" @@ -5053,7 +5160,7 @@ msgstr "টেনে আনাৰ সৰ্বোচ্চ সীমা" #: gtk/gtksettings.c:330 msgid "Number of pixels the cursor can move before dragging" -msgstr "টেনে নেওয়াৰ পূৰ্বে কাৰ্সাৰটি যি সংখ্যক পিক্সেল নড়তে পাৰে" +msgstr "টেনে নেওয়াৰ পূৰ্বে কাৰ্ছাৰটি যি সংখ্যক পিক্সেল নড়তে পাৰে" #: gtk/gtksettings.c:338 msgid "Font Name" @@ -5069,7 +5176,7 @@ msgstr "আইকনেৰ আয়তন" #: gtk/gtksettings.c:362 msgid "List of icon sizes (gtk-menu=16,16:gtk-button=20,20..." -msgstr "আইকনেৰ আকাৰেৰ তালিকা (gtk-menu= ১৬, ১৬:gtk-button=২০,২০..." +msgstr "আইকনেৰ আকাৰৰ তালিকা (gtk-menu= ১৬, ১৬:gtk-button=২০,২০..." #: gtk/gtksettings.c:370 msgid "GTK Modules" @@ -5077,7 +5184,7 @@ msgstr "জি.টি.কে. মডিউল" #: gtk/gtksettings.c:371 msgid "List of currently active GTK modules" -msgstr "বৰ্তমানে সক্ৰিয় জি.টি.কে. মডিউলেৰ তালিকা" +msgstr "বৰ্তমানে সক্ৰিয় জি.টি.কে. মডিউলৰ তালিকা" #: gtk/gtksettings.c:380 msgid "Xft Antialias" @@ -5123,7 +5230,7 @@ msgstr "" #: gtk/gtksettings.c:430 msgid "Cursor theme name" -msgstr "কাৰ্সাৰ থিমেৰ নাম" +msgstr "কাৰ্ছাৰ থিমেৰ নাম" #: gtk/gtksettings.c:431 msgid "Name of the cursor theme to use, or NULL to use the default theme" @@ -5131,7 +5238,7 @@ msgstr "নাম সৰ্বমোট" #: gtk/gtksettings.c:439 msgid "Cursor theme size" -msgstr "কাৰ্সাৰ থিমেৰ আকাৰ" +msgstr "কাৰ্ছাৰ থিমেৰ আকাৰ" #: gtk/gtksettings.c:440 msgid "Size to use for cursors, or 0 to use the default size" @@ -5143,7 +5250,7 @@ msgstr "বিকল্প বুটাম-বিন্যাস" #: gtk/gtksettings.c:451 msgid "Whether buttons in dialogs should use the alternative button order" -msgstr "ডায়ালগেৰ বুটামসমূহ বিকল্প বুটাম-বিন্যাস ব্যৱহাৰ কৰবে নে নাই" +msgstr "ডায়ালগেৰ বুটামসমূহ বিকল্প বুটাম-বিন্যাস ব্যৱহাৰ কৰিব নে নাই" #: gtk/gtksettings.c:468 msgid "Alternative sort indicator direction" @@ -5177,7 +5284,7 @@ msgid "" "control characters" msgstr "" "এন্ট্ৰিৰ কনটেক্সট তালিকা আৰু টেক্সট প্ৰদৰ্শন ব্যৱস্থাৰ দ্বাৰা কন্ট্ৰোল ক্যাৰেক্টাৰ " -"সন্নিবেশেৰ সুবিধা উপলব্ধ কৰা হ'ব কি না" +"সন্নিবেশৰ সুবিধা উপলব্ধ কৰা হ'ব কি না" #: gtk/gtksettings.c:495 msgid "Start timeout" @@ -5362,12 +5469,12 @@ msgstr "Timestamp of current fontconfig configuration" # #: gtk/gtksettings.c:897 msgid "Sound Theme Name" -msgstr "শব্দের থিমের নাম" +msgstr "শব্দেৰ থিমেৰ নাম" # #: gtk/gtksettings.c:898 msgid "XDG sound theme name" -msgstr "কাৰ্সাৰ থিমেৰ নাম" +msgstr "কাৰ্ছাৰ থিমেৰ নাম" #. Translators: this means sounds that are played as feedback to user input #: gtk/gtksettings.c:920 @@ -5399,21 +5506,21 @@ msgstr "টুল-টিপ সক্ৰিয় কৰা হ'ব" msgid "Whether tooltips should be shown on widgets" msgstr "ট্যাব প্ৰদৰ্শন কৰা হ'ব নে নাই" -#: gtk/gtksizegroup.c:293 +#: gtk/gtksizegroup.c:301 msgid "Mode" msgstr "মোড (Mode)" -#: gtk/gtksizegroup.c:294 +#: gtk/gtksizegroup.c:302 msgid "" "The directions in which the size group affects the requested sizes of its " "component widgets" -msgstr "আকাৰেৰ গ্ৰুপ তাৰ কম্পোনেন্ট উইজেটগুলোৰ আবেদনকৃত আকাৰকে যি দিকে প্ৰভাবিত কৰে" +msgstr "আকাৰৰ গ্ৰুপ তাৰ কম্পোনেন্ট উইজেটগুলোৰ আবেদনকৃত আকাৰকে যি দিকে প্ৰভাবিত কৰি" -#: gtk/gtksizegroup.c:310 +#: gtk/gtksizegroup.c:318 msgid "Ignore hidden" msgstr "লুকানো উইজেটকে অগ্ৰাহ্য কৰো" -#: gtk/gtksizegroup.c:311 +#: gtk/gtksizegroup.c:319 msgid "" "If TRUE, unmapped widgets are ignored when determining the size of the group" msgstr "সৰ্বমোট" @@ -5452,7 +5559,7 @@ msgstr "গুটানো" #: gtk/gtkspinbutton.c:253 msgid "Whether a spin button should wrap upon reaching its limits" -msgstr "স্পিন বুটাম তাৰ সৰ্বোচ্চ সীমায় পৌঁছে গুটিয়ে সৰ্বনিম্ন মানে নেমে যাবে নে নাই" +msgstr "স্পিন বুটাম তাৰ সৰ্বোচ্চ সীমায় পৌঁছে গুটিয়ে সৰ্বনিম্ন মানে নেমে যাব নে নাই" #: gtk/gtkspinbutton.c:260 msgid "Update Policy" @@ -5461,15 +5568,15 @@ msgstr "আপডেট কৰাৰ নীতি" #: gtk/gtkspinbutton.c:261 msgid "" "Whether the spin button should update always, or only when the value is legal" -msgstr "স্পিন বুটাম কখন আপডেট কৰবে - সৰ্বদা নাকি কেবল মানটি বৈধ হলেই" +msgstr "স্পিন বুটাম কখন আপডেট কৰিব - সৰ্বদা নাকি কেবল মানটি বৈধ হলেই" #: gtk/gtkspinbutton.c:270 msgid "Reads the current value, or sets a new value" -msgstr "বৰ্তমান মানটি পড়ে অথবা নতুন মান নিৰ্ধাৰণ কৰে" +msgstr "বৰ্তমান মানটি পড়ে অথবা নতুন মান নিৰ্ধাৰণ কৰি" #: gtk/gtkspinbutton.c:279 msgid "Style of bevel around the spin button" -msgstr "স্পিন বুটামৰ চতুপাৰ্শ্বস্থ বেভেলেৰ ধৰন" +msgstr "স্পিন বুটামৰ চতুপাৰ্শ্বস্থ বেভেলৰ ধৰন" #: gtk/gtkstatusbar.c:141 msgid "Has Resize Grip" @@ -5477,67 +5584,71 @@ msgstr "আকাৰ পৰিবৰ্তনেৰ ক্ষমতা আছে #: gtk/gtkstatusbar.c:142 msgid "Whether the statusbar has a grip for resizing the toplevel" -msgstr "ওপৰতেৰ স্তৰেৰ আকাৰ পৰিবৰ্তনেৰ ক্ষমতা স্ট্যটাসবাৰেৰ আছে নে নাই" +msgstr "ওপৰতেৰ স্তৰৰ আকাৰ পৰিবৰ্তনেৰ ক্ষমতা স্ট্যটাসবাৰৰ আছে নে নাই" #: gtk/gtkstatusbar.c:187 msgid "Style of bevel around the statusbar text" -msgstr "স্ট্যাটাসবাৰ টেক্সটৰ চাৰপাশে প্ৰদৰ্শিত বেভেলেৰ ধৰন" +msgstr "স্ট্যাটাসবাৰ টেক্সটৰ চাৰপাশে প্ৰদৰ্শিত বেভেলৰ ধৰন" -#: gtk/gtkstatusicon.c:268 +#: gtk/gtkstatusicon.c:271 msgid "The size of the icon" msgstr "সৰ্বমোট" -#: gtk/gtkstatusicon.c:278 +#: gtk/gtkstatusicon.c:281 msgid "The screen where this status icon will be displayed" msgstr "The screen where this status icon will be displayed" # -#: gtk/gtkstatusicon.c:285 +#: gtk/gtkstatusicon.c:288 msgid "Blinking" msgstr "ঢিমিক-ঢামাক " -#: gtk/gtkstatusicon.c:286 +#: gtk/gtkstatusicon.c:289 msgid "Whether or not the status icon is blinking" msgstr "হলো" -#: gtk/gtkstatusicon.c:294 +#: gtk/gtkstatusicon.c:297 msgid "Whether or not the status icon is visible" msgstr "হলো দৃশ্যমান" -#: gtk/gtkstatusicon.c:310 +#: gtk/gtkstatusicon.c:313 msgid "Whether or not the status icon is embedded" msgstr "হলো" -#: gtk/gtkstatusicon.c:326 gtk/gtktrayicon-x11.c:111 +#: gtk/gtkstatusicon.c:329 gtk/gtktrayicon-x11.c:111 msgid "The orientation of the tray" msgstr "সৰ্বমোট" -#: gtk/gtkstatusicon.c:353 gtk/gtkwidget.c:632 +#: gtk/gtkstatusicon.c:356 gtk/gtkwidget.c:634 msgid "Has tooltip" msgstr "Has tooltip" # -#: gtk/gtkstatusicon.c:354 +#: gtk/gtkstatusicon.c:357 msgid "Whether this tray icon has a tooltip" -msgstr "এই ট্যাগ (tag) ফন্ট আকাৰকে প্ৰভাবিত কৰে নে নাই" +msgstr "এই ট্যাগ (tag) ফন্ট আকাৰকে প্ৰভাবিত কৰি নে নাই" -#: gtk/gtkstatusicon.c:375 gtk/gtkwidget.c:653 +#: gtk/gtkstatusicon.c:382 gtk/gtkwidget.c:655 msgid "Tooltip Text" msgstr "টুলটিপ Text" -#: gtk/gtkstatusicon.c:376 gtk/gtkwidget.c:654 gtk/gtkwidget.c:675 +#: gtk/gtkstatusicon.c:383 gtk/gtkwidget.c:656 gtk/gtkwidget.c:677 msgid "The contents of the tooltip for this widget" msgstr "সৰ্বমোট উল্লিখিত সময় অবধি" -#: gtk/gtkstatusicon.c:399 gtk/gtkwidget.c:674 +#: gtk/gtkstatusicon.c:406 gtk/gtkwidget.c:676 msgid "Tooltip markup" msgstr "টুলটিপ" # -#: gtk/gtkstatusicon.c:400 +#: gtk/gtkstatusicon.c:407 msgid "The contents of the tooltip for this tray icon" msgstr "সৰ্বমোট উল্লিখিত সময় অবধি" +#: gtk/gtkstatusicon.c:425 +msgid "The title of this tray icon" +msgstr "এই ট্ৰে আইকণৰ শিৰোনাম" + #: gtk/gtktable.c:129 msgid "Rows" msgstr "Rows" @@ -5576,11 +5687,11 @@ msgstr "প্ৰস্থ দৈৰ্ঘ্য" #: gtk/gtktable.c:173 msgid "Left attachment" -msgstr "বামপাশেৰ সংৰেখন" +msgstr "বামপাশৰ সংৰেখন" #: gtk/gtktable.c:180 msgid "Right attachment" -msgstr "ডানপাশেৰ সংৰেখন" +msgstr "ডানপাশৰ সংৰেখন" #: gtk/gtktable.c:181 msgid "The column number to attach the right side of a child widget to" @@ -5684,7 +5795,7 @@ msgstr "Whether the buffer has some text currently selected" #: gtk/gtktextbuffer.c:230 msgid "Cursor position" -msgstr "কাৰ্সাৰেৰ অবস্থান" +msgstr "কাৰ্ছাৰৰ অবস্থান" #: gtk/gtktextbuffer.c:231 msgid "" @@ -5802,11 +5913,11 @@ msgid "" "adapts to theme changes etc. so is recommended. Pango predefines some scales " "such as PANGO_SCALE_X_LARGE" msgstr "" -"ফন্টৰ অবিকল্পিত আকাৰেৰ গুণিতক হিচাপে ফন্টৰ আকাৰ। ইয়াক পৰিবৰ্তিত থিমেৰ সৈতে " -"ভালভাবে খাপখাইয়ে নেয় বিধায় ইয়াক ব্যৱহাৰেৰ পৰামৰ্শ দিয়া গেল। পেনগো কিছু গুণিতক, " -"যিমন PANGO_SCALE_X_LARGE তৰ মান পূৰ্বৰ পৰা নিৰ্ধাৰণ কৰে থাকে।" +"ফন্টৰ অবিকল্পিত আকাৰৰ গুণিতক হিচাপে ফন্টৰ আকাৰ। ইয়াক পৰিবৰ্তিত থিমেৰ সৈতে " +"ভালভাবে খাপখাইয়ে নেয় বিধায় ইয়াক ব্যৱহাৰৰ পৰামৰ্শ দিয়া গেল। পেনগো কিছু গুণিতক, " +"যিমন PANGO_SCALE_X_LARGE তৰ মান পূৰ্বৰ পৰা নিৰ্ধাৰণ কৰি থাকে।" -#: gtk/gtktexttag.c:360 gtk/gtktextview.c:591 +#: gtk/gtktexttag.c:360 gtk/gtktextview.c:592 msgid "Left, right, or center justification" msgstr "বাম, ডান অথবা কেন্দ্ৰীয় জাস্টিফিকেশন (Justification)" @@ -5823,7 +5934,7 @@ msgstr "" msgid "Left margin" msgstr "বাঁ দিকেৰ মাৰ্জিন" -#: gtk/gtktexttag.c:387 gtk/gtktextview.c:600 +#: gtk/gtktexttag.c:387 gtk/gtktextview.c:601 msgid "Width of the left margin in pixels" msgstr "বাঁ দিকেৰ মাৰ্জিনেৰ প্ৰস্থ (পিক্সেলে)" @@ -5831,15 +5942,15 @@ msgstr "বাঁ দিকেৰ মাৰ্জিনেৰ প্ৰস্থ msgid "Right margin" msgstr "ডান দিকেৰ মাৰ্জিন" -#: gtk/gtktexttag.c:397 gtk/gtktextview.c:610 +#: gtk/gtktexttag.c:397 gtk/gtktextview.c:611 msgid "Width of the right margin in pixels" msgstr "ডান দিকেৰ মাৰ্জিনেৰ প্ৰস্থ (পিক্সেলে)" -#: gtk/gtktexttag.c:407 gtk/gtktextview.c:619 +#: gtk/gtktexttag.c:407 gtk/gtktextview.c:620 msgid "Indent" msgstr "ইনডেন্ট" -#: gtk/gtktexttag.c:408 gtk/gtktextview.c:620 +#: gtk/gtktexttag.c:408 gtk/gtktextview.c:621 msgid "Amount to indent the paragraph, in pixels" msgstr "অনুচ্ছেদটিকে মাৰ্জিনৰ পৰা যত পিক্সেল ছাড় দেয়া হ'ব" @@ -5855,7 +5966,7 @@ msgstr "" msgid "Pixels above lines" msgstr "লাইনেৰ ওপৰতে পিক্ছেলৰসংখ্যা" -#: gtk/gtktexttag.c:429 gtk/gtktextview.c:544 +#: gtk/gtktexttag.c:429 gtk/gtktextview.c:545 msgid "Pixels of blank space above paragraphs" msgstr "অনুচ্ছেদেৰ ওপৰ যত পিক্সেল ৰিক্ত স্থান থাকবে" @@ -5863,7 +5974,7 @@ msgstr "অনুচ্ছেদেৰ ওপৰ যত পিক্সেল msgid "Pixels below lines" msgstr "লাইনেৰ তলে পিক্ছেলৰসংখ্যা" -#: gtk/gtktexttag.c:439 gtk/gtktextview.c:554 +#: gtk/gtktexttag.c:439 gtk/gtktextview.c:555 msgid "Pixels of blank space below paragraphs" msgstr "অনুচ্ছেদেৰ তলে যত পিক্সেল ৰিক্ত স্থান থাকবে" @@ -5871,24 +5982,24 @@ msgstr "অনুচ্ছেদেৰ তলে যত পিক্সেল msgid "Pixels inside wrap" msgstr "গুটিয়ে নেয়াৰ ক্ষেত্ৰে পিক্সেল সংখ্যা" -#: gtk/gtktexttag.c:449 gtk/gtktextview.c:564 +#: gtk/gtktexttag.c:449 gtk/gtktextview.c:565 msgid "Pixels of blank space between wrapped lines in a paragraph" msgstr "কোন অনুচ্ছেদেৰ গুটিয়ে যাওয়া দুটি লাইনেৰ মাজত যত পিক্সেল ফাঁক থাকবে" -#: gtk/gtktexttag.c:476 gtk/gtktextview.c:582 +#: gtk/gtktexttag.c:476 gtk/gtktextview.c:583 msgid "" "Whether to wrap lines never, at word boundaries, or at character boundaries" msgstr "" "লাইন কখনোই গুটিয়ে নেয়া নহ'ব, শব্দ শেষ হলে গুটিয়ে নেয়া নহ'বকি অক্ষৰ শেষ হলে গুটিয়ে " "নেয়া হ'ব" -#: gtk/gtktexttag.c:485 gtk/gtktextview.c:629 +#: gtk/gtktexttag.c:485 gtk/gtktextview.c:630 msgid "Tabs" msgstr "ট্যাব" -#: gtk/gtktexttag.c:486 gtk/gtktextview.c:630 +#: gtk/gtktexttag.c:486 gtk/gtktextview.c:631 msgid "Custom tabs for this text" -msgstr "এই টেক্সটৰ বাবে ইচ্ছামাফিক আকাৰেৰ ট্যাব" +msgstr "এই টেক্সটৰ বাবে ইচ্ছামাফিক আকাৰৰ ট্যাব" #: gtk/gtktexttag.c:504 msgid "Invisible" @@ -5928,7 +6039,7 @@ msgstr "পটভূমিৰ পূৰ্ণ উচ্চতাৰ সেট" #: gtk/gtktexttag.c:569 msgid "Whether this tag affects background height" -msgstr "এই ট্যাগটি পটভূমিৰ উচ্চতাকে প্ৰভাবিত কৰে নে নাই" +msgstr "এই ট্যাগটি পটভূমিৰ উচ্চতাকে প্ৰভাবিত কৰি নে নাই" #: gtk/gtktexttag.c:572 msgid "Background stipple set" @@ -5936,7 +6047,7 @@ msgstr "পটভূমি আঁকায় ব্যৱহৃত বিন্দ #: gtk/gtktexttag.c:573 msgid "Whether this tag affects the background stipple" -msgstr "এই ট্যাগটি পটভূমি আঁকায় ব্যৱহৃত বিন্দুৰ সেটকে প্ৰভাবিত কৰে নে নাই" +msgstr "এই ট্যাগটি পটভূমি আঁকায় ব্যৱহৃত বিন্দুৰ সেটকে প্ৰভাবিত কৰি নে নাই" #: gtk/gtktexttag.c:580 msgid "Foreground stipple set" @@ -5944,7 +6055,7 @@ msgstr "পুৰোভূমি আঁকায় ব্যৱহৃত বিন #: gtk/gtktexttag.c:581 msgid "Whether this tag affects the foreground stipple" -msgstr "এই ট্যাগটি পুৰোভূমি আঁকায় ব্যৱহৃত বিন্দুৰ সেটকে প্ৰভাবিত কৰে নে নাই" +msgstr "এই ট্যাগটি পুৰোভূমি আঁকায় ব্যৱহৃত বিন্দুৰ সেটকে প্ৰভাবিত কৰি নে নাই" #: gtk/gtktexttag.c:616 msgid "Justification set" @@ -5952,7 +6063,7 @@ msgstr "জাস্টিফিকেশন সেট" #: gtk/gtktexttag.c:617 msgid "Whether this tag affects paragraph justification" -msgstr "এই ট্যাগটি অনুচ্ছেদেৰ জাস্টিফিকেশনে সাহায্য কৰে নে নাই" +msgstr "এই ট্যাগটি অনুচ্ছেদেৰ জাস্টিফিকেশনে সাহায্য কৰি নে নাই" #: gtk/gtktexttag.c:624 msgid "Left margin set" @@ -5960,7 +6071,7 @@ msgstr "বাম দিকেৰ মাৰ্জিন সেট" #: gtk/gtktexttag.c:625 msgid "Whether this tag affects the left margin" -msgstr "এই ট্যাগটি বাম দিকেৰ মাৰ্জিনকে প্ৰভাবিত কৰে নে নাই" +msgstr "এই ট্যাগটি বাম দিকেৰ মাৰ্জিনকে প্ৰভাবিত কৰি নে নাই" #: gtk/gtktexttag.c:628 msgid "Indent set" @@ -5968,7 +6079,7 @@ msgstr "অবচ্ছেদ সেট" #: gtk/gtktexttag.c:629 msgid "Whether this tag affects indentation" -msgstr "এই ট্যাগটি অবচ্ছেদনকে প্ৰভাবিত কৰে নে নাই" +msgstr "এই ট্যাগটি অবচ্ছেদনকে প্ৰভাবিত কৰি নে নাই" #: gtk/gtktexttag.c:636 msgid "Pixels above lines set" @@ -5976,7 +6087,7 @@ msgstr "লাইন সেটেৰ ওপৰে পিক্সেল" #: gtk/gtktexttag.c:637 gtk/gtktexttag.c:641 msgid "Whether this tag affects the number of pixels above lines" -msgstr "এই ট্যাগটি লাইন সেটেৰ ওপৰ পিক্ছেলৰসংখ্যা প্ৰভাবিত কৰে নে নাই" +msgstr "এই ট্যাগটি লাইন সেটেৰ ওপৰ পিক্ছেলৰসংখ্যা প্ৰভাবিত কৰি নে নাই" #: gtk/gtktexttag.c:640 msgid "Pixels below lines set" @@ -5989,7 +6100,7 @@ msgstr "গুটিয়ে যাওয়াৰ সেটেৰ মাজত প #: gtk/gtktexttag.c:645 msgid "Whether this tag affects the number of pixels between wrapped lines" msgstr "" -"এই ট্যাগটি গুটিয়ে যাওয়া লাইনসমূহেৰ মাজত অবস্থিত পিক্ছেলৰসংখ্যাকে প্ৰভাবিত কৰে নে নাই" +"এই ট্যাগটি গুটিয়ে যাওয়া লাইনসমূহেৰ মাজত অবস্থিত পিক্ছেলৰসংখ্যাকে প্ৰভাবিত কৰি নে নাই" #: gtk/gtktexttag.c:652 msgid "Right margin set" @@ -5997,7 +6108,7 @@ msgstr "ডান দিকেৰ মাৰ্জিন সেট" #: gtk/gtktexttag.c:653 msgid "Whether this tag affects the right margin" -msgstr "এই ট্যাগটি ডান দিকেৰ মাৰ্জিনকে প্ৰভাবিত কৰে নে নাই" +msgstr "এই ট্যাগটি ডান দিকেৰ মাৰ্জিনকে প্ৰভাবিত কৰি নে নাই" #: gtk/gtktexttag.c:660 msgid "Wrap mode set" @@ -6005,7 +6116,7 @@ msgstr "গুটিয়ে যাওয়াৰ মোড সেট" #: gtk/gtktexttag.c:661 msgid "Whether this tag affects line wrap mode" -msgstr "এই ট্যাগটি লাইন গুটিয়ে যাওয়াৰ সেটকে প্ৰভাবিত কৰে নে নাই" +msgstr "এই ট্যাগটি লাইন গুটিয়ে যাওয়াৰ সেটকে প্ৰভাবিত কৰি নে নাই" #: gtk/gtktexttag.c:664 msgid "Tabs set" @@ -6013,7 +6124,7 @@ msgstr "ট্যাব সেট" #: gtk/gtktexttag.c:665 msgid "Whether this tag affects tabs" -msgstr "এই ট্যাগটি ট্যাবকে প্ৰভাবিত কৰে নে নাই" +msgstr "এই ট্যাগটি ট্যাবকে প্ৰভাবিত কৰি নে নাই" #: gtk/gtktexttag.c:668 msgid "Invisible set" @@ -6021,7 +6132,7 @@ msgstr "অদৃশ্য সেট" #: gtk/gtktexttag.c:669 msgid "Whether this tag affects text visibility" -msgstr "এই ট্যাগটি টেক্সটৰ দৃষ্টিগ্ৰাহ্যতা প্ৰভাবিত কৰে নে নাই" +msgstr "এই ট্যাগটি টেক্সটৰ দৃষ্টিগ্ৰাহ্যতা প্ৰভাবিত কৰি নে নাই" #: gtk/gtktexttag.c:672 msgid "Paragraph background set" @@ -6029,65 +6140,65 @@ msgstr "অনুচ্ছেদেৰ পটভূমিৰ সেট" #: gtk/gtktexttag.c:673 msgid "Whether this tag affects the paragraph background color" -msgstr "এই ট্যাগটি অনুচ্ছেদেৰ পটভূমিৰ ৰঙকে প্ৰভাবিত কৰে নে নাই" +msgstr "এই ট্যাগটি অনুচ্ছেদেৰ পটভূমিৰ ৰঙকে প্ৰভাবিত কৰি নে নাই" -#: gtk/gtktextview.c:543 +#: gtk/gtktextview.c:544 msgid "Pixels Above Lines" msgstr "লাইনেৰ ওপৰতে পিক্ছেলৰসংখ্যা" -#: gtk/gtktextview.c:553 +#: gtk/gtktextview.c:554 msgid "Pixels Below Lines" msgstr "লাইনেৰ তলে পিক্ছেলৰসংখ্যা" -#: gtk/gtktextview.c:563 +#: gtk/gtktextview.c:564 msgid "Pixels Inside Wrap" msgstr "জড়ানোৰ মাজতকাৰ পিক্ছেলৰসংখ্যা" -#: gtk/gtktextview.c:581 +#: gtk/gtktextview.c:582 msgid "Wrap Mode" msgstr "জড়ানো (wrap) অবস্থা" -#: gtk/gtktextview.c:599 +#: gtk/gtktextview.c:600 msgid "Left Margin" msgstr "বাঁদিকেৰ মাৰ্জিন" -#: gtk/gtktextview.c:609 +#: gtk/gtktextview.c:610 msgid "Right Margin" msgstr "সোঁফালৰ মাৰ্জিন" -#: gtk/gtktextview.c:637 -msgid "Cursor Visible" -msgstr "কাৰ্সাৰ দৃশ্যমান" - #: gtk/gtktextview.c:638 -msgid "If the insertion cursor is shown" -msgstr "যদি লেখা ভৰোৱাৰ (Insetion) কাৰ্সাৰ প্ৰদৰ্শন কৰা হয়" +msgid "Cursor Visible" +msgstr "কাৰ্ছাৰ দৃশ্যমান" -#: gtk/gtktextview.c:645 +#: gtk/gtktextview.c:639 +msgid "If the insertion cursor is shown" +msgstr "যদি লেখা ভৰোৱাৰ (Insetion) কাৰ্ছাৰ প্ৰদৰ্শন কৰা হয়" + +#: gtk/gtktextview.c:646 msgid "Buffer" msgstr "বাফাৰ" -#: gtk/gtktextview.c:646 +#: gtk/gtktextview.c:647 msgid "The buffer which is displayed" msgstr "যি বাফাৰটি প্ৰদৰ্শন কৰা হয়" -#: gtk/gtktextview.c:654 +#: gtk/gtktextview.c:655 msgid "Whether entered text overwrites existing contents" msgstr "যি টেক্সট লেখা হ'ব তা বিদ্যমান টেক্সটৰ ওপৰ দিয়ে লেখা হ'ব নে নাই" -#: gtk/gtktextview.c:661 -msgid "Accepts tab" -msgstr "ট্যাব তৰ ব্যৱহাৰ অনুমোদন কৰে" - #: gtk/gtktextview.c:662 +msgid "Accepts tab" +msgstr "ট্যাব তৰ ব্যৱহাৰ অনুমোদন কৰি" + +#: gtk/gtktextview.c:663 msgid "Whether Tab will result in a tab character being entered" msgstr "ট্যাব চাপলে যি অক্ষৰটি লেখা হ'ব তা ট্যাব-ই হ'ব নে নাই" -#: gtk/gtktextview.c:691 +#: gtk/gtktextview.c:692 msgid "Error underline color" msgstr "ভুল নিৰ্দেশক নিম্নৰেখাৰ ৰং" -#: gtk/gtktextview.c:692 +#: gtk/gtktextview.c:693 msgid "Color with which to draw error-indication underlines" msgstr "ভুল নিৰ্দেশক নিম্নৰেখা আঁকতে যি ৰং ব্যৱহৃত হ'ব" @@ -6121,7 +6232,7 @@ msgstr "যদি বুটামৰ টোগল অংশটি প্ৰদ #: gtk/gtktoolbar.c:494 msgid "Toolbar Style" -msgstr "টুল-বাৰেৰ বিন্যাস" +msgstr "টুল-বাৰৰ বিন্যাস" #: gtk/gtktoolbar.c:495 msgid "How to draw the toolbar" @@ -6141,7 +6252,7 @@ msgstr "টুলটিপ" #: gtk/gtktoolbar.c:519 msgid "If the tooltips of the toolbar should be active or not" -msgstr "টুলবাৰেৰ টুলটিপ সক্ৰিয় থাকবে নে নাই" +msgstr "টুলবাৰৰ টুলটিপ সক্ৰিয় থাকবে নে নাই" #: gtk/gtktoolbar.c:541 msgid "Size of icons in this toolbar" @@ -6157,7 +6268,7 @@ msgstr "Whether the icon-size property has been set" #: gtk/gtktoolbar.c:566 msgid "Whether the item should receive extra space when the toolbar grows" -msgstr "টুলবাৰেৰ আকৃতি বৃদ্ধি পেলে জিনিষটি অতিৰিক্ত স্থান দখল কৰবে নে নাই" +msgstr "টুলবাৰৰ আকৃতি বৃদ্ধি পেলে জিনিষটি অতিৰিক্ত স্থান দখল কৰিব নে নাই" #: gtk/gtktoolbar.c:574 msgid "Whether the item should be the same size as other homogeneous items" @@ -6173,7 +6284,7 @@ msgstr "স্পেসাৰ (Spacer) ইয়াৰ আকাৰ" #: gtk/gtktoolbar.c:591 msgid "Amount of border space between the toolbar shadow and the buttons" -msgstr "টুলবাৰেৰ ছায়া আৰু বুটামসমূহেৰ মাজত প্ৰান্তীয় স্থান" +msgstr "টুলবাৰৰ ছায়া আৰু বুটামসমূহেৰ মাজত প্ৰান্তীয় স্থান" #: gtk/gtktoolbar.c:599 msgid "Maximum child expand" @@ -6197,15 +6308,15 @@ msgstr "বুটাম ছেড়ে দেয়া" #: gtk/gtktoolbar.c:617 msgid "Type of bevel around toolbar buttons" -msgstr "টুলবাৰে অবস্থিত বুটামৰ চাৰদিকে বেভেলেৰ ধৰন" +msgstr "টুলবাৰে অবস্থিত বুটামৰ চাৰদিকে বেভেলৰ ধৰন" #: gtk/gtktoolbar.c:624 msgid "Style of bevel around the toolbar" -msgstr "টুলবাৰেৰ চাৰদিকে বেভেলেৰ ধৰন" +msgstr "টুলবাৰৰ চাৰদিকে বেভেলৰ ধৰন" #: gtk/gtktoolbar.c:630 msgid "Toolbar style" -msgstr "টুলবাৰেৰ ধৰন" +msgstr "টুলবাৰৰ ধৰন" #: gtk/gtktoolbar.c:631 msgid "" @@ -6215,7 +6326,7 @@ msgstr "" #: gtk/gtktoolbar.c:637 msgid "Toolbar icon size" -msgstr "টুলবাৰেৰ আইকনেৰ আয়তন" +msgstr "টুলবাৰৰ আইকনেৰ আয়তন" #: gtk/gtktoolbar.c:638 msgid "Size of icons in default toolbars" @@ -6230,7 +6341,7 @@ msgid "" "If set, an underline in the label property indicates that the next character " "should be used for the mnemonic accelerator key in the overflow menu" msgstr "" -"এটি বাছাই কৰা থাকলে, লেবেলেৰ বৈশিষ্ট্য নিৰ্দেশ কৰে যি, পৰবৰ্তী অক্ষৰটি ওভাৰফ্লো " +"এটি বাছাই কৰা থাকলে, লেবেলৰ বৈশিষ্ট্য নিৰ্দেশ কৰি যি, পৰবৰ্তী অক্ষৰটি ওভাৰফ্লো " "মেনুতে নেমোনিক চটপট কী (Key) হিচাপে ব্যৱহৃত হ'ব" #: gtk/gtktoolbutton.c:217 @@ -6269,347 +6380,355 @@ msgstr "আইকন" msgid "Spacing in pixels between the icon and label" msgstr "মধ্যবৰ্তী স্থান পিকসেল" -#: gtk/gtktoolitem.c:191 +#: gtk/gtktoolitem.c:207 msgid "" "Whether the toolbar item is considered important. When TRUE, toolbar buttons " "show text in GTK_TOOLBAR_BOTH_HORIZ mode" msgstr "" "টুলবাৰ আইটেমকে গুৰুত্বপূৰ্ণ বিবেচনা কৰা হয় নে নাই। ইয়াৰ মান সত্য (TRUE) হলে, টুলবাৰ " -"বুটাম GTK_TOOLBAR_BOTH_HORIZ মোডে টেক্সট প্ৰদৰ্শন কৰে" +"বুটাম GTK_TOOLBAR_BOTH_HORIZ মোডে টেক্সট প্ৰদৰ্শন কৰি" -#: gtk/gtktreemodelsort.c:274 +#: gtk/gtktreemodelsort.c:278 msgid "TreeModelSort Model" msgstr "TreeModelSort মডেল" -#: gtk/gtktreemodelsort.c:275 +#: gtk/gtktreemodelsort.c:279 msgid "The model for the TreeModelSort to sort" -msgstr "TreeModelSort তৰ যি মডেলকে ক্ৰমানুসাৰ সাজানো হ'ব" +msgstr "TreeModelSort তৰ যি মডেলকে ক্ৰমানুসাৰ সজোৱাৰ হ'ব" -#: gtk/gtktreeview.c:570 +#: gtk/gtktreeview.c:561 msgid "TreeView Model" msgstr "ট্ৰি-ভিউ মডেল" -#: gtk/gtktreeview.c:571 +#: gtk/gtktreeview.c:562 msgid "The model for the tree view" msgstr "ট্ৰি-ভিউ তৰ মডেল" -#: gtk/gtktreeview.c:579 +#: gtk/gtktreeview.c:570 msgid "Horizontal Adjustment for the widget" msgstr "উইজেটেৰ পথালি সমন্বয়" -#: gtk/gtktreeview.c:587 +#: gtk/gtktreeview.c:578 msgid "Vertical Adjustment for the widget" msgstr "উইজেটেৰ উলম্ব সমন্বয়" -#: gtk/gtktreeview.c:594 +#: gtk/gtktreeview.c:585 msgid "Headers Visible" msgstr "হেডাৰ দৃশ্যমান থাকবে" -#: gtk/gtktreeview.c:595 +#: gtk/gtktreeview.c:586 msgid "Show the column header buttons" -msgstr "স্তম্ভ হেডাৰেৰ বুটাম প্ৰদৰ্শন কৰো" +msgstr "স্তম্ভ হেডাৰৰ বুটাম প্ৰদৰ্শন কৰো" -#: gtk/gtktreeview.c:602 +#: gtk/gtktreeview.c:593 msgid "Headers Clickable" msgstr "ক্লিক কৰাৰ যোগ্য হেডাৰ" -#: gtk/gtktreeview.c:603 +#: gtk/gtktreeview.c:594 msgid "Column headers respond to click events" msgstr "স্তম্ভ হেডাৰ ক্লিক ইভেন্টসমূহে সাড়া দেয়" -#: gtk/gtktreeview.c:610 +#: gtk/gtktreeview.c:601 msgid "Expander Column" msgstr "বৰ্ধিষ্ণু (Expander) স্তম্ভ" -#: gtk/gtktreeview.c:611 +#: gtk/gtktreeview.c:602 msgid "Set the column for the expander column" msgstr "স্তম্ভটি প্ৰকৃতি বৰ্ধিষ্ণু (Expander) স্তম্ভ হিচাপে নিৰ্ধাৰণ কৰো" -#: gtk/gtktreeview.c:626 +#: gtk/gtktreeview.c:617 msgid "Rules Hint" msgstr "নিয়ম সংক্ৰান্ত ইঙ্গিত" -#: gtk/gtktreeview.c:627 +#: gtk/gtktreeview.c:618 msgid "Set a hint to the theme engine to draw rows in alternating colors" msgstr "" "পৰিবৰ্তনশীল ৰঙে শাৰী আঁকাৰ উদ্দেশ্যি থিম ইঞ্জিনেৰ বাবেি এটা ইঙ্গিত নিৰ্ধাৰণ কৰো" -#: gtk/gtktreeview.c:634 +#: gtk/gtktreeview.c:625 msgid "Enable Search" msgstr "অনুসন্ধান প্ৰক্ৰিয়া সক্ৰিয় কৰো" -#: gtk/gtktreeview.c:635 +#: gtk/gtktreeview.c:626 msgid "View allows user to search through columns interactively" msgstr "" "এই দৃশ্যটি ব্যৱহাৰকাৰীৰ অংশগ্ৰহণেৰ মধ্য দিয়ে (Interactive) স্তম্ভৰ পৰা অনুসন্ধান " "চালাতে দেয়" -#: gtk/gtktreeview.c:642 +#: gtk/gtktreeview.c:633 msgid "Search Column" msgstr "অনুসন্ধানেৰ স্তম্ভ" # -#: gtk/gtktreeview.c:643 +#: gtk/gtktreeview.c:634 msgid "Model column to search through during interactive search" msgstr "কোড অনুসন্ধানেৰ সময় যি মডেল স্তম্ভে অনুসন্ধান চালানো হ'ব" -#: gtk/gtktreeview.c:663 +#: gtk/gtktreeview.c:654 msgid "Fixed Height Mode" msgstr "পূৰ্বনিৰ্দিষ্ট উচ্চতা ব্যৱহাৰকাৰী মোড" -#: gtk/gtktreeview.c:664 +#: gtk/gtktreeview.c:655 msgid "Speeds up GtkTreeView by assuming that all rows have the same height" -msgstr "সকল শাৰীৰ উচ্চতা সমান বিবেচনা কৰে GtkTreeView-কে দ্ৰুততৰ কৰে" +msgstr "সকল শাৰীৰ উচ্চতা সমান বিবেচনা কৰি GtkTreeView-কে দ্ৰুততৰ কৰি" -#: gtk/gtktreeview.c:684 +#: gtk/gtktreeview.c:675 msgid "Hover Selection" msgstr "ভাসমান (Hover) নিৰ্বাচন" -#: gtk/gtktreeview.c:685 +#: gtk/gtktreeview.c:676 msgid "Whether the selection should follow the pointer" -msgstr "পয়েন্টাৰকে অনুসৰণ কৰে নিৰ্বাচন কৰা হ'ব নে নাই" +msgstr "পইন্টাৰক অনুসৰণ কৰি নিৰ্বাচন কৰা হ'ব নে নাই" -#: gtk/gtktreeview.c:704 +#: gtk/gtktreeview.c:695 msgid "Hover Expand" msgstr "ভাসমান (Hover) সম্প্ৰসাৰণ" -#: gtk/gtktreeview.c:705 +#: gtk/gtktreeview.c:696 msgid "" "Whether rows should be expanded/collapsed when the pointer moves over them" -msgstr "কোন শাৰীৰ ওপৰ পয়েন্টাৰ ৰাখা হলে তাকে সম্প্ৰসাৰিত-কৰা/খোলা হ'ব নে নাই" +msgstr "কোন শাৰীৰ ওপৰ পইন্টাৰ ৰাখা হলে তাকে সম্প্ৰসাৰিত-কৰা/খোলা হ'ব নে নাই" -#: gtk/gtktreeview.c:719 +#: gtk/gtktreeview.c:710 msgid "Show Expanders" msgstr "Show Expanders" -#: gtk/gtktreeview.c:720 +#: gtk/gtktreeview.c:711 msgid "View has expanders" msgstr "প্ৰদৰ্শন" -#: gtk/gtktreeview.c:734 +#: gtk/gtktreeview.c:725 msgid "Level Indentation" msgstr "Level Indentation" -#: gtk/gtktreeview.c:735 +#: gtk/gtktreeview.c:726 msgid "Extra indentation for each level" msgstr "উল্লিখিত সময় অবধি" -#: gtk/gtktreeview.c:744 +#: gtk/gtktreeview.c:735 msgid "Rubber Banding" msgstr "Rubber Banding" -#: gtk/gtktreeview.c:745 +#: gtk/gtktreeview.c:736 msgid "" "Whether to enable selection of multiple items by dragging the mouse pointer" msgstr "সৰ্বমোট" -#: gtk/gtktreeview.c:752 +#: gtk/gtktreeview.c:743 msgid "Enable Grid Lines" msgstr "সক্ৰিয় কৰক পংক্তি" -#: gtk/gtktreeview.c:753 +#: gtk/gtktreeview.c:744 msgid "Whether grid lines should be drawn in the tree view" msgstr "খানি পংক্তিৰ বাবে" -#: gtk/gtktreeview.c:761 +#: gtk/gtktreeview.c:752 msgid "Enable Tree Lines" msgstr "সক্ৰিয় কৰক ট্ৰি পংক্তি" -#: gtk/gtktreeview.c:762 +#: gtk/gtktreeview.c:753 msgid "Whether tree lines should be drawn in the tree view" msgstr "খানি পংক্তিৰ বাবে" -#: gtk/gtktreeview.c:770 +#: gtk/gtktreeview.c:761 msgid "The column in the model containing the tooltip texts for the rows" msgstr "উল্লিখিত সময় অবধি শাৰী" -#: gtk/gtktreeview.c:792 +#: gtk/gtktreeview.c:783 msgid "Vertical Separator Width" msgstr "উলম্ব বিভাজকেৰ প্ৰস্থ" -#: gtk/gtktreeview.c:793 +#: gtk/gtktreeview.c:784 msgid "Vertical space between cells. Must be an even number" -msgstr "দুটি ঘৰেৰ মাজত উলম্ব স্থান। ইয়াক অবশ্যই এটা জোড় সংখ্যা হ'ব" +msgstr "দুটি ঘৰৰ মাজত উলম্ব স্থান। ইয়াক অবশ্যই এটা জোড় সংখ্যা হ'ব" -#: gtk/gtktreeview.c:801 +#: gtk/gtktreeview.c:792 msgid "Horizontal Separator Width" msgstr "পথালি বিভাজকেৰ প্ৰস্থ" -#: gtk/gtktreeview.c:802 +#: gtk/gtktreeview.c:793 msgid "Horizontal space between cells. Must be an even number" -msgstr "দুটি ঘৰেৰ মাজত পথালি স্থান। ইয়াক অবশ্যই এটা জোড় সংখ্যা হ'ব" +msgstr "দুটি ঘৰৰ মাজত পথালি স্থান। ইয়াক অবশ্যই এটা জোড় সংখ্যা হ'ব" -#: gtk/gtktreeview.c:810 +#: gtk/gtktreeview.c:801 msgid "Allow Rules" msgstr "নিয়ম অনুমোদন কৰো" -#: gtk/gtktreeview.c:811 +#: gtk/gtktreeview.c:802 msgid "Allow drawing of alternating color rows" msgstr "পৰিবৰ্তনশীল ৰং দিয়ে শাৰী আঁকা অনুমোদন কৰো" -#: gtk/gtktreeview.c:817 +#: gtk/gtktreeview.c:808 msgid "Indent Expanders" msgstr "অবচ্ছেদ (Indent) প্ৰসাৰক" -#: gtk/gtktreeview.c:818 +#: gtk/gtktreeview.c:809 msgid "Make the expanders indented" msgstr "প্ৰসাৰকসমূহক অবচ্ছেদিত (Indented) কৰো" -#: gtk/gtktreeview.c:824 +#: gtk/gtktreeview.c:815 msgid "Even Row Color" -msgstr "জোড় নম্বৰেৰ শাৰীৰ ৰং" +msgstr "জোড় নম্বৰৰ শাৰীৰ ৰং" -#: gtk/gtktreeview.c:825 +#: gtk/gtktreeview.c:816 msgid "Color to use for even rows" -msgstr "জোড় নম্বৰেৰ শাৰীতে ব্যৱহৃত ৰং" +msgstr "জোড় নম্বৰৰ শাৰীতে ব্যৱহৃত ৰং" -#: gtk/gtktreeview.c:831 +#: gtk/gtktreeview.c:822 msgid "Odd Row Color" -msgstr "বেজোড় নম্বৰেৰ শাৰীৰ ৰং" +msgstr "বেজোড় নম্বৰৰ শাৰীৰ ৰং" -#: gtk/gtktreeview.c:832 +#: gtk/gtktreeview.c:823 msgid "Color to use for odd rows" -msgstr "বেজোড় নম্বৰেৰ শাৰীতে ব্যৱহৃত ৰং" +msgstr "বেজোড় নম্বৰৰ শাৰীতে ব্যৱহৃত ৰং" -#: gtk/gtktreeview.c:838 +#: gtk/gtktreeview.c:829 msgid "Row Ending details" msgstr "শাৰী" -#: gtk/gtktreeview.c:839 +#: gtk/gtktreeview.c:830 msgid "Enable extended row background theming" msgstr "সক্ৰিয় কৰক" -#: gtk/gtktreeview.c:845 +#: gtk/gtktreeview.c:836 msgid "Grid line width" msgstr "প্ৰস্থ" -#: gtk/gtktreeview.c:846 +#: gtk/gtktreeview.c:837 msgid "Width, in pixels, of the tree view grid lines" msgstr "Width পিকসেল সৰ্বমোট খানি পংক্তিৰ বাবে" -#: gtk/gtktreeview.c:852 +#: gtk/gtktreeview.c:843 msgid "Tree line width" msgstr "ট্ৰি প্ৰস্থ" -#: gtk/gtktreeview.c:853 +#: gtk/gtktreeview.c:844 msgid "Width, in pixels, of the tree view lines" msgstr "Width পিকসেল সৰ্বমোট খানি পংক্তিৰ বাবে" -#: gtk/gtktreeview.c:859 +#: gtk/gtktreeview.c:850 msgid "Grid line pattern" msgstr "Grid line pattern" -#: gtk/gtktreeview.c:860 +#: gtk/gtktreeview.c:851 msgid "Dash pattern used to draw the tree view grid lines" msgstr "খানি পংক্তিৰ বাবে" -#: gtk/gtktreeview.c:866 +#: gtk/gtktreeview.c:857 msgid "Tree line pattern" msgstr "ট্ৰি" -#: gtk/gtktreeview.c:867 +#: gtk/gtktreeview.c:858 msgid "Dash pattern used to draw the tree view lines" msgstr "খানি পংক্তিৰ বাবে" -#: gtk/gtktreeviewcolumn.c:192 +#: gtk/gtktreeviewcolumn.c:193 msgid "Whether to display the column" msgstr "স্তম্ভ প্ৰদৰ্শন কৰা হ'ব নে নাই" -#: gtk/gtktreeviewcolumn.c:199 gtk/gtkwindow.c:537 +#: gtk/gtktreeviewcolumn.c:200 gtk/gtkwindow.c:537 msgid "Resizable" msgstr "পৰিবৰ্তনযোগ্য আকাৰ" -#: gtk/gtktreeviewcolumn.c:200 +#: gtk/gtktreeviewcolumn.c:201 msgid "Column is user-resizable" msgstr "ব্যৱহাৰকাৰীকৰ্তৃক পৰিবৰ্তনযোগ্য স্তম্ভেৰ আকাৰ" -#: gtk/gtktreeviewcolumn.c:208 +#: gtk/gtktreeviewcolumn.c:209 msgid "Current width of the column" msgstr "স্তম্ভেৰ বৰ্তমান প্ৰস্থ" -#: gtk/gtktreeviewcolumn.c:217 +#: gtk/gtktreeviewcolumn.c:218 msgid "Space which is inserted between cells" msgstr "ঘৰগুলোৰ মাজতৰ স্থানে যি স্থান ভৰোৱা হয়" -#: gtk/gtktreeviewcolumn.c:225 +#: gtk/gtktreeviewcolumn.c:226 msgid "Sizing" msgstr "আকাৰ প্ৰদান" -#: gtk/gtktreeviewcolumn.c:226 +#: gtk/gtktreeviewcolumn.c:227 msgid "Resize mode of the column" msgstr "স্তম্ভেৰ আকাৰ পৰিবৰ্তন মোড" -#: gtk/gtktreeviewcolumn.c:234 +#: gtk/gtktreeviewcolumn.c:235 msgid "Fixed Width" msgstr "পূৰ্বনিৰ্দিষ্ট প্ৰস্থ" -#: gtk/gtktreeviewcolumn.c:235 +#: gtk/gtktreeviewcolumn.c:236 msgid "Current fixed width of the column" msgstr "স্তম্ভেৰ বৰ্তমান পূৰ্বনিৰ্দিষ্ট প্ৰস্থ" -#: gtk/gtktreeviewcolumn.c:244 +#: gtk/gtktreeviewcolumn.c:245 msgid "Minimum Width" msgstr "সৰ্বনিম্ন প্ৰস্থ" -#: gtk/gtktreeviewcolumn.c:245 +#: gtk/gtktreeviewcolumn.c:246 msgid "Minimum allowed width of the column" msgstr "স্তম্ভেৰ সৰ্বনিম্ন অনুমোদনযোগ্য প্ৰস্থ" -#: gtk/gtktreeviewcolumn.c:254 +#: gtk/gtktreeviewcolumn.c:255 msgid "Maximum Width" msgstr "সৰ্বোচ্চ প্ৰস্থ" -#: gtk/gtktreeviewcolumn.c:255 +#: gtk/gtktreeviewcolumn.c:256 msgid "Maximum allowed width of the column" msgstr "স্তম্ভেৰ সৰ্বোচ্চ অনুমোদনযোগ্য প্ৰস্থ" -#: gtk/gtktreeviewcolumn.c:265 +#: gtk/gtktreeviewcolumn.c:266 msgid "Title to appear in column header" -msgstr "স্তম্ভ হেডাৰে যি শিৰোনাম দেখা যাবে" +msgstr "স্তম্ভ হেডাৰে যি শিৰোনাম দেখা যাব" -#: gtk/gtktreeviewcolumn.c:273 +#: gtk/gtktreeviewcolumn.c:274 msgid "Column gets share of extra width allocated to the widget" -msgstr "উইজেটকে যি অতিৰিক্ত স্থান বৰাদ্দদ্দ্ককৰা হয়, স্তম্ভ তাৰ অংশবিশেষ ব্যৱহাৰ কৰে" +msgstr "উইজেটকে যি অতিৰিক্ত স্থান বৰাদ্দদ্দ্ককৰা হয়, স্তম্ভ তাৰ অংশবিশেষ ব্যৱহাৰ কৰি" -#: gtk/gtktreeviewcolumn.c:280 +#: gtk/gtktreeviewcolumn.c:281 msgid "Clickable" msgstr "ক্লিকযোগ্য" -#: gtk/gtktreeviewcolumn.c:281 +#: gtk/gtktreeviewcolumn.c:282 msgid "Whether the header can be clicked" -msgstr "হেডাৰ ক্লিক কৰা যাবে নে নাই" +msgstr "হেডাৰ ক্লিক কৰা যাব নে নাই" -#: gtk/gtktreeviewcolumn.c:289 +#: gtk/gtktreeviewcolumn.c:290 msgid "Widget" msgstr "উইজেট" -#: gtk/gtktreeviewcolumn.c:290 +#: gtk/gtktreeviewcolumn.c:291 msgid "Widget to put in column header button instead of column title" msgstr "স্তম্ভ শিৰোনামেৰ পৰিবৰ্তে স্তম্ভ হেডাৰ বুটাম তৈৰিৰ উইজেট" -#: gtk/gtktreeviewcolumn.c:298 +#: gtk/gtktreeviewcolumn.c:299 msgid "X Alignment of the column header text or widget" msgstr "স্তম্ভ হেডাৰ টেক্সট বা উইজেটেৰ এক্স সংৰেখন" -#: gtk/gtktreeviewcolumn.c:308 +#: gtk/gtktreeviewcolumn.c:309 msgid "Whether the column can be reordered around the headers" -msgstr "হেডাৰেৰ চাৰপাশে স্তম্ভকে পুনৰায় বিন্যস্ত কৰা যাবে নে নাই" - -#: gtk/gtktreeviewcolumn.c:315 -msgid "Sort indicator" -msgstr "ক্ৰমানুসাৰে সাজানো নিৰ্দেশক" +msgstr "হেডাৰৰ চাৰপাশে স্তম্ভকে পুনৰায় বিন্যস্ত কৰা যাব নে নাই" #: gtk/gtktreeviewcolumn.c:316 -msgid "Whether to show a sort indicator" -msgstr "সাজানো নিৰ্দেশক প্ৰদৰ্শন কৰা হ'ব নে নাই" +msgid "Sort indicator" +msgstr "ক্ৰমানুসাৰে সজোৱাৰ নিৰ্দেশক" -#: gtk/gtktreeviewcolumn.c:323 -msgid "Sort order" -msgstr "সাজানোৰ ধাৰা" +#: gtk/gtktreeviewcolumn.c:317 +msgid "Whether to show a sort indicator" +msgstr "সজোৱাৰ নিৰ্দেশক প্ৰদৰ্শন কৰা হ'ব নে নাই" #: gtk/gtktreeviewcolumn.c:324 +msgid "Sort order" +msgstr "সজোৱাৰ ধাৰা" + +#: gtk/gtktreeviewcolumn.c:325 msgid "Sort direction the sort indicator should indicate" -msgstr "সাজানো নিৰ্দেশকটি যি সাজানোৰ ধাৰা নিৰ্দেশক কৰবে" +msgstr "সজোৱাৰ নিৰ্দেশক যি সজোৱাৰ ধাৰা নিৰ্দেশকে কৰিব" + +#: gtk/gtktreeviewcolumn.c:341 +msgid "Sort column ID" +msgstr "স্তম্ভৰ ID সজাওক" + +#: gtk/gtktreeviewcolumn.c:342 +msgid "Logical sort column ID this column sorts on when selected for sorting" +msgstr "সজোৱাৰ কাৰণে নিৰ্বাচন কৰাৰ পিছত এই স্তম্ভই সজোৱা লজিকেলভাবে সজোৱা স্তম্ভৰ " #: gtk/gtkuimanager.c:223 msgid "Whether tearoff menu items should be added to menus" @@ -6637,29 +6756,29 @@ msgstr "ভিউপোৰ্টেৰ উলম্ব অবস্থান ন #: gtk/gtkviewport.c:123 msgid "Determines how the shadowed box around the viewport is drawn" -msgstr "শ্যাডো বাক্স'ৰ চাৰপাশে কিভাবে ভিউপোৰ্ট আঁকা হ'ব তা নিৰ্ধাৰণ কৰে" +msgstr "শ্যাডো বাক্স'ৰ চাৰপাশে কিভাবে ভিউপোৰ্ট আঁকা হ'ব তা নিৰ্ধাৰণ কৰি" -#: gtk/gtkwidget.c:483 +#: gtk/gtkwidget.c:485 msgid "Widget name" msgstr "উইজেটেৰ নাম" -#: gtk/gtkwidget.c:484 +#: gtk/gtkwidget.c:486 msgid "The name of the widget" msgstr "উইজেটেৰ নাম" -#: gtk/gtkwidget.c:490 +#: gtk/gtkwidget.c:492 msgid "Parent widget" msgstr "পেৰেন্ট উইজেট" -#: gtk/gtkwidget.c:491 +#: gtk/gtkwidget.c:493 msgid "The parent widget of this widget. Must be a Container widget" msgstr "এই উইজেটেৰ পেৰেন্ট উইজেট। এটিকে অবশ্যই এটা কনটেইনাৰ উইজেট হতে হ'ব" -#: gtk/gtkwidget.c:498 +#: gtk/gtkwidget.c:500 msgid "Width request" msgstr "প্ৰস্থেৰ বাবে অনুৰোধ" -#: gtk/gtkwidget.c:499 +#: gtk/gtkwidget.c:501 msgid "" "Override for width request of the widget, or -1 if natural request should be " "used" @@ -6667,11 +6786,11 @@ msgstr "" "উইজেটেৰ প্ৰস্থ বিষয়ক আবেদন অগ্ৰাহ্যকাৰী মান; ইয়াৰ মান -১ হলে স্বাভাবিক আবেদন " "অনুমোদন কৰা হ'ব" -#: gtk/gtkwidget.c:507 +#: gtk/gtkwidget.c:509 msgid "Height request" msgstr "উচ্চতাৰ বাবে অনুৰোধ" -#: gtk/gtkwidget.c:508 +#: gtk/gtkwidget.c:510 msgid "" "Override for height request of the widget, or -1 if natural request should " "be used" @@ -6679,215 +6798,223 @@ msgstr "" "উইজেটেৰ দৈৰ্ঘ্য বিষয়ক আবেদন অগ্ৰাহ্যকাৰী মান; ইয়াৰ মান -১ হলে স্বাভাবিক আবেদন " "অনুমোদন কৰা হ'ব" -#: gtk/gtkwidget.c:517 +#: gtk/gtkwidget.c:519 msgid "Whether the widget is visible" msgstr "উইজেট দৃশ্যমান নে নাই" -#: gtk/gtkwidget.c:524 +#: gtk/gtkwidget.c:526 msgid "Whether the widget responds to input" msgstr "ইনপুটেৰ প্ৰতি উইজেট সাড়া দেয় নে নাই" -#: gtk/gtkwidget.c:530 +#: gtk/gtkwidget.c:532 msgid "Application paintable" msgstr "আঁকাৰযোগ্য অ্যাপলিকেশন" -#: gtk/gtkwidget.c:531 +#: gtk/gtkwidget.c:533 msgid "Whether the application will paint directly on the widget" msgstr "অ্যাপলিকেশনটি সৰাসৰি উইজেটে আঁকবে নে নাই" -#: gtk/gtkwidget.c:537 +#: gtk/gtkwidget.c:539 msgid "Can focus" msgstr "ফোকাস কৰতে পাৰে" -#: gtk/gtkwidget.c:538 +#: gtk/gtkwidget.c:540 msgid "Whether the widget can accept the input focus" msgstr "উইজেটটি ইনপুটেৰ ফ'কাচ গ্ৰহণ কৰতে পাৰে নে নাই" -#: gtk/gtkwidget.c:544 +#: gtk/gtkwidget.c:546 msgid "Has focus" msgstr "ফোকাস আছে" -#: gtk/gtkwidget.c:545 +#: gtk/gtkwidget.c:547 msgid "Whether the widget has the input focus" msgstr "উইজেটটিৰ ইনপুট ফ'কাচ আছে নে নাই" -#: gtk/gtkwidget.c:551 +#: gtk/gtkwidget.c:553 msgid "Is focus" msgstr "ফোকাস" -#: gtk/gtkwidget.c:552 +#: gtk/gtkwidget.c:554 msgid "Whether the widget is the focus widget within the toplevel" -msgstr "উইজেটটি সৰ্বোচ্চ স্তৰেৰ ফ'কাচ উইজেট নে নাই" +msgstr "উইজেটটি সৰ্বোচ্চ স্তৰৰ ফ'কাচ উইজেট নে নাই" -#: gtk/gtkwidget.c:558 +#: gtk/gtkwidget.c:560 msgid "Can default" msgstr "অবিকল্পিত হতে পাৰে" -#: gtk/gtkwidget.c:559 +#: gtk/gtkwidget.c:561 msgid "Whether the widget can be the default widget" msgstr "উইজেটটি অবিকল্পিত উইজেট হতে পাৰবে নে নাই" -#: gtk/gtkwidget.c:565 +#: gtk/gtkwidget.c:567 msgid "Has default" msgstr "অবিকল্পিত আছে" -#: gtk/gtkwidget.c:566 +#: gtk/gtkwidget.c:568 msgid "Whether the widget is the default widget" msgstr "উইজেটটি অবিকল্পিত উইজেট নে নাই" -#: gtk/gtkwidget.c:572 +#: gtk/gtkwidget.c:574 msgid "Receives default" -msgstr "অবিকল্পিত গ্ৰহণ কৰে" +msgstr "অবিকল্পিত গ্ৰহণ কৰি" -#: gtk/gtkwidget.c:573 +#: gtk/gtkwidget.c:575 msgid "If TRUE, the widget will receive the default action when it is focused" -msgstr "যদি TRUE হয় তেন্তে ফোকাসকৃত অবস্থায় উইজেটটি অবিকল্পিত অ্যাকশন গ্ৰহণ কৰবে" +msgstr "যদি TRUE হয় তেন্তে ফোকাসকৃত অবস্থায় উইজেটটি অবিকল্পিত অ্যাকশন গ্ৰহণ কৰিব" -#: gtk/gtkwidget.c:579 +#: gtk/gtkwidget.c:581 msgid "Composite child" msgstr "কম্পোসিট চাইল্ড" -#: gtk/gtkwidget.c:580 +#: gtk/gtkwidget.c:582 msgid "Whether the widget is part of a composite widget" msgstr "উইজেটটি কোন কম্পোসিট চাইল্ডৰ অংশ নে নাই" -#: gtk/gtkwidget.c:586 +#: gtk/gtkwidget.c:588 msgid "Style" msgstr "বিন্যাস" -#: gtk/gtkwidget.c:587 +#: gtk/gtkwidget.c:589 msgid "" "The style of the widget, which contains information about how it will look " "(colors etc)" -msgstr "উইজেটেৰ ধৰন, যা উইজেটেৰ চেহাৰা সংক্ৰান্ত তথ্য ধাৰণ কৰে (ৰং ইত্যাদি)" +msgstr "উইজেটেৰ ধৰন, যাৰ উইজেটেৰ চেহাৰা সংক্ৰান্ত তথ্য ধাৰণ কৰি (ৰং ইত্যাদি)" -#: gtk/gtkwidget.c:593 +#: gtk/gtkwidget.c:595 msgid "Events" msgstr "ঘটনাসমূহ " -#: gtk/gtkwidget.c:594 +#: gtk/gtkwidget.c:596 msgid "The event mask that decides what kind of GdkEvents this widget gets" msgstr "" -"যি ইভেন্ট মাস্কটি নিৰ্ধাৰণ কৰে এই উইজেটটি কি ধৰনেৰ GdkEvents গ্ৰহণ কৰতে পাৰে" +"যি ইভেন্ট মাস্কটি নিৰ্ধাৰণ কৰি এই উইজেটটি কি ধৰনেৰ GdkEvents গ্ৰহণ কৰতে পাৰে" -#: gtk/gtkwidget.c:601 +#: gtk/gtkwidget.c:603 msgid "Extension events" msgstr "বৰ্ধিত ইভেন্ট" -#: gtk/gtkwidget.c:602 +#: gtk/gtkwidget.c:604 msgid "The mask that decides what kind of extension events this widget gets" -msgstr "যি মাস্কটি নিৰ্ধাৰণ কৰে এই উইজেটটি কি ধৰনেৰ বৰ্ধিত ইভেন্ট গ্ৰহণ কৰতে পাৰে" +msgstr "যি মাস্কটি নিৰ্ধাৰণ কৰি এই উইজেটটি কি ধৰনেৰ বৰ্ধিত ইভেন্ট গ্ৰহণ কৰতে পাৰে" -#: gtk/gtkwidget.c:609 +#: gtk/gtkwidget.c:611 msgid "No show all" msgstr "সবকিছু দেখাও অকেজো" -#: gtk/gtkwidget.c:610 +#: gtk/gtkwidget.c:612 msgid "Whether gtk_widget_show_all() should not affect this widget" -msgstr "gtk_widget_show_all() এই উইজেটকে প্ৰভাবিত কৰবে না নে নাই" +msgstr "gtk_widget_show_all() এই উইজেটকে প্ৰভাবিত কৰিব না নে নাই" -#: gtk/gtkwidget.c:633 +#: gtk/gtkwidget.c:635 msgid "Whether this widget has a tooltip" msgstr "Whether this widget has a tooltip" # -#: gtk/gtkwidget.c:689 +#: gtk/gtkwidget.c:691 msgid "Window" msgstr "সংযোগ পথ" -#: gtk/gtkwidget.c:690 +#: gtk/gtkwidget.c:692 msgid "The widget's window if it is realized" msgstr "The widget's window if it is realized" -#: gtk/gtkwidget.c:2212 +#: gtk/gtkwidget.c:706 +msgid "Double Buffered" +msgstr "ডাবুল বাফাৰ" + +#: gtk/gtkwidget.c:707 +msgid "Whether or not the widget is double buffered" +msgstr "ৱিজেটক ডাবুল বাফাৰ কৰা হৈছে নে নাই" + +#: gtk/gtkwidget.c:2229 msgid "Interior Focus" msgstr "অভ্যন্তৰীণ ফোকাস" -#: gtk/gtkwidget.c:2213 +#: gtk/gtkwidget.c:2230 msgid "Whether to draw the focus indicator inside widgets" msgstr "ফোকাস নিৰ্দেশকটি উইজেটেৰ ভেতৰ আঁকা হ'ব নে নাই" -#: gtk/gtkwidget.c:2219 +#: gtk/gtkwidget.c:2236 msgid "Focus linewidth" -msgstr "ফোকাসেৰ লাইনব্যাপ্তি" +msgstr "ফোকাসৰ লাইনব্যাপ্তি" -#: gtk/gtkwidget.c:2220 +#: gtk/gtkwidget.c:2237 msgid "Width, in pixels, of the focus indicator line" msgstr "পিক্সেল হিচাপে ফ'কাচ নিৰ্দেশক লাইনেৰ প্ৰস্থ" -#: gtk/gtkwidget.c:2226 +#: gtk/gtkwidget.c:2243 msgid "Focus line dash pattern" msgstr "ফোকাস লাইনেৰ ড্যাশ পেটাৰ্ন" -#: gtk/gtkwidget.c:2227 +#: gtk/gtkwidget.c:2244 msgid "Dash pattern used to draw the focus indicator" msgstr "ফোকাস নিৰ্দেশক আঁকতে যি ধৰনেৰ ড্যাশ পেটাৰ্ন আঁকতে হ'ব" -#: gtk/gtkwidget.c:2232 +#: gtk/gtkwidget.c:2249 msgid "Focus padding" msgstr "ফোকাস পেডিং" -#: gtk/gtkwidget.c:2233 +#: gtk/gtkwidget.c:2250 msgid "Width, in pixels, between focus indicator and the widget 'box'" msgstr "পিক্সেল হিচাপে ফ'কাচ নিৰ্দেশক আৰু উইজেট 'বক্সৰ' মধ্যবৰ্তী স্থানেৰ প্ৰস্থ" -#: gtk/gtkwidget.c:2238 +#: gtk/gtkwidget.c:2255 msgid "Cursor color" -msgstr "কাৰ্সাৰেৰ ৰং " +msgstr "কাৰ্ছাৰৰ ৰং " -#: gtk/gtkwidget.c:2239 +#: gtk/gtkwidget.c:2256 msgid "Color with which to draw insertion cursor" -msgstr "অক্ষৰ ভৰোৱাৰ (Insertion) কাৰ্সাৰ আঁকতে যি ৰং ব্যৱহৃত হ'ব" +msgstr "অক্ষৰ ভৰোৱাৰ (Insertion) কাৰ্ছাৰ আঁকতে যি ৰং ব্যৱহৃত হ'ব" -#: gtk/gtkwidget.c:2244 +#: gtk/gtkwidget.c:2261 msgid "Secondary cursor color" -msgstr "কাৰ্সাৰ আঁকায় ব্যৱহৃত দ্বিতীয় ৰং" +msgstr "কাৰ্ছাৰ আঁকায় ব্যৱহৃত দ্বিতীয় ৰং" -#: gtk/gtkwidget.c:2245 +#: gtk/gtkwidget.c:2262 msgid "" "Color with which to draw the secondary insertion cursor when editing mixed " "right-to-left and left-to-right text" msgstr "" "ডান-থেকে-বাম এবং বাম-থেকে-ডান এ লেখায় হয় ইয়াৰকম টেক্সটৰ মিশ্ৰণ এডিট কৰাৰ সময় " -"অক্ষৰ ভৰোৱাৰ (Insertion) কাৰ্সাৰ আঁকতে যি ৰং ব্যৱহৃত হ'ব" +"অক্ষৰ ভৰোৱাৰ (Insertion) কাৰ্ছাৰ আঁকতে যি ৰং ব্যৱহৃত হ'ব" -#: gtk/gtkwidget.c:2250 +#: gtk/gtkwidget.c:2267 msgid "Cursor line aspect ratio" -msgstr "কাৰ্সাৰ লাইনেৰ আবয়ব অনুপাত" +msgstr "কাৰ্ছাৰ লাইনেৰ আবয়ব অনুপাত" -#: gtk/gtkwidget.c:2251 +#: gtk/gtkwidget.c:2268 msgid "Aspect ratio with which to draw insertion cursor" -msgstr "যি আবয়ব অনুপাতে অক্ষৰ ভৰোৱাৰ (Insertion) কাৰ্সাৰ আঁকা হ'ব" +msgstr "যি আবয়ব অনুপাতে অক্ষৰ ভৰোৱাৰ (Insertion) কাৰ্ছাৰ আঁকা হ'ব" -#: gtk/gtkwidget.c:2265 +#: gtk/gtkwidget.c:2282 msgid "Draw Border" msgstr "প্ৰান্ত আঁকো" -#: gtk/gtkwidget.c:2266 +#: gtk/gtkwidget.c:2283 msgid "Size of areas outside the widget's allocation to draw" -msgstr "উইজেটেৰ বৰাদ্দকৃত অংশেৰ বাইৰে যিখানে আঁকা হ'ব তাৰ আকাৰ" +msgstr "উইজেটেৰ বৰাদ্দকৃত অংশৰ বাইৰে যিখানে আঁকা হ'ব তাৰ আকাৰ" -#: gtk/gtkwidget.c:2279 +#: gtk/gtkwidget.c:2296 msgid "Unvisited Link Color" msgstr "সংযোগ" -#: gtk/gtkwidget.c:2280 +#: gtk/gtkwidget.c:2297 msgid "Color of unvisited links" msgstr "সৰ্বমোট" -#: gtk/gtkwidget.c:2293 +#: gtk/gtkwidget.c:2310 msgid "Visited Link Color" msgstr "পৰিদৰ্শিত সংযোগেৰ ৰং" -#: gtk/gtkwidget.c:2294 +#: gtk/gtkwidget.c:2311 msgid "Color of visited links" msgstr "সৰ্বমোট" -#: gtk/gtkwidget.c:2308 +#: gtk/gtkwidget.c:2325 msgid "Wide Separators" msgstr "Wide Separators" -#: gtk/gtkwidget.c:2309 +#: gtk/gtkwidget.c:2326 msgid "" "Whether separators have configurable width and should be drawn using a box " "instead of a line" @@ -6895,35 +7022,35 @@ msgstr "" "Whether separators have configurable width and should be drawn using a box " "instead of a line" -#: gtk/gtkwidget.c:2323 +#: gtk/gtkwidget.c:2340 msgid "Separator Width" msgstr "বিভাজন ৰেখা Width" -#: gtk/gtkwidget.c:2324 +#: gtk/gtkwidget.c:2341 msgid "The width of separators if wide-separators is TRUE" msgstr "প্ৰস্থ সৰ্বমোট হলো" -#: gtk/gtkwidget.c:2338 +#: gtk/gtkwidget.c:2355 msgid "Separator Height" msgstr "বিভাজন ৰেখা উচ্চতা" -#: gtk/gtkwidget.c:2339 +#: gtk/gtkwidget.c:2356 msgid "The height of separators if \"wide-separators\" is TRUE" msgstr "দৈৰ্ঘ্য সৰ্বমোট হলো" -#: gtk/gtkwidget.c:2353 +#: gtk/gtkwidget.c:2370 msgid "Horizontal Scroll Arrow Length" msgstr "Horizontal Scroll Arrow Length" -#: gtk/gtkwidget.c:2354 +#: gtk/gtkwidget.c:2371 msgid "The length of horizontal scroll arrows" msgstr "সৰ্বমোট" -#: gtk/gtkwidget.c:2368 +#: gtk/gtkwidget.c:2385 msgid "Vertical Scroll Arrow Length" msgstr "Vertical Scroll Arrow Length" -#: gtk/gtkwidget.c:2369 +#: gtk/gtkwidget.c:2386 msgid "The length of vertical scroll arrows" msgstr "সৰ্বমোট" @@ -6949,7 +7076,7 @@ msgstr "উইন্ডোৰ ভূমিকা" #: gtk/gtkwindow.c:496 msgid "Unique identifier for the window to be used when restoring a session" -msgstr "কোন সেশন পুনৰুদ্ধাৰেৰ সময় উইন্ডোৰ বাবে যি একক (Unique) নিৰ্দেশক ব্যৱহৃত হ'ব" +msgstr "কোন সেশন পুনৰুদ্ধাৰৰ সময় উইন্ডোৰ বাবে যি একক (Unique) নিৰ্দেশক ব্যৱহৃত হ'ব" #: gtk/gtkwindow.c:512 msgid "Startup ID" @@ -6995,8 +7122,8 @@ msgid "" "If TRUE, the window is modal (other windows are not usable while this one is " "up)" msgstr "" -"যদি TRUE হয় তেন্তে উইন্ডোটো মোডাল (এই উইন্ডোটি যখন দেখা যাবে থাকবে তখন অন্যান্য " -"উইন্ডো ব্যৱহাৰ কৰা যাবে না)" +"যদি TRUE হয় তেন্তে উইন্ডোটো মোডাল (এই উইন্ডোটি যখন দেখা যাব থাকবে তখন অন্যান্য " +"উইন্ডো ব্যৱহাৰ কৰা যাব না)" #: gtk/gtkwindow.c:553 msgid "Window Position" @@ -7029,7 +7156,7 @@ msgstr "পেৰেন্ট সাথেই বন্ধ কৰো" #: gtk/gtkwindow.c:583 msgid "If this window should be destroyed when the parent is destroyed" -msgstr "পেৰেন্ট উইন্ডো বন্ধ কৰে দিলে এই উইন্ডোটিও বন্ধ কৰা হ'ব নে নাই" +msgstr "পেৰেন্ট উইন্ডো বন্ধ কৰি দিলে এই উইন্ডোটিও বন্ধ কৰা হ'ব নে নাই" #: gtk/gtkwindow.c:591 msgid "Icon for this window" @@ -7049,7 +7176,7 @@ msgstr "সৰ্বোচ্চ স্তৰটি বৰ্তমানে স #: gtk/gtkwindow.c:630 msgid "Focus in Toplevel" -msgstr "ওপৰতেৰ স্তৰেৰ ফোকাস" +msgstr "ওপৰতেৰ স্তৰৰ ফোকাস" #: gtk/gtkwindow.c:631 msgid "Whether the input focus is within this GtkWindow" @@ -7097,15 +7224,15 @@ msgstr "ফোকাস অনুমোদন কৰো" #: gtk/gtkwindow.c:679 msgid "TRUE if the window should receive the input focus." -msgstr "উইন্ডোটি ইনপুট ফোকাসেৰ লক্ষ্য হলে ইয়াৰ মান TRUE ।" +msgstr "উইন্ডোটি ইনপুট ফোকাসৰ লক্ষ্য হলে ইয়াৰ মান TRUE ।" #: gtk/gtkwindow.c:693 msgid "Focus on map" -msgstr "মানচিত্ৰেৰ ওপৰ ফ'কাচ কৰো" +msgstr "মানচিত্ৰৰ ওপৰ ফ'কাচ কৰো" #: gtk/gtkwindow.c:694 msgid "TRUE if the window should receive the input focus when mapped." -msgstr "ইয়াৰ মান সত্য (TRUE) হলে উইন্ডোটি ইনপুট ফোকাসেৰ লক্ষ্য হ'ব।" +msgstr "ইয়াৰ মান সত্য (TRUE) হলে উইন্ডোটি ইনপুট ফোকাসৰ লক্ষ্য হ'ব।" #: gtk/gtkwindow.c:708 msgid "Decorated" @@ -7113,7 +7240,7 @@ msgstr "সজ্জিত" #: gtk/gtkwindow.c:709 msgid "Whether the window should be decorated by the window manager" -msgstr "উইন্ডো ব্যৱস্থাপক উইন্ডোটি সজ্জিত কৰবে নে নাই" +msgstr "উইন্ডো ব্যৱস্থাপক উইন্ডোটি সজ্জিত কৰিব নে নাই" #: gtk/gtkwindow.c:723 msgid "Deletable" diff --git a/po-properties/ast.po b/po-properties/ast.po index 3a8f1eeb7a..69c22e2a7a 100644 --- a/po-properties/ast.po +++ b/po-properties/ast.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: ast\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-06-15 20:53-0400\n" +"POT-Creation-Date: 2009-09-30 17:31-0400\n" "PO-Revision-Date: 2009-01-25 13:10+0200\n" "Last-Translator: Esbardu \n" "Language-Team: Asturian \n" @@ -15,6 +15,14 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +#: gdk-pixbuf/gdk-pixbuf-simple-anim.c:165 +msgid "Loop" +msgstr "" + +#: gdk-pixbuf/gdk-pixbuf-simple-anim.c:166 +msgid "Whether the animation should loop when it reaches the end" +msgstr "" + #: gdk-pixbuf/gdk-pixbuf.c:89 msgid "Number of Channels" msgstr "" @@ -47,7 +55,7 @@ msgstr "" msgid "The number of bits per sample" msgstr "" -#: gdk-pixbuf/gdk-pixbuf.c:132 gtk/gtklayout.c:632 gtk/gtktreeviewcolumn.c:207 +#: gdk-pixbuf/gdk-pixbuf.c:132 gtk/gtklayout.c:632 gtk/gtktreeviewcolumn.c:208 msgid "Width" msgstr "" @@ -88,12 +96,12 @@ msgstr "" msgid "The default display for GDK" msgstr "" -#: gdk/gdkpango.c:537 gtk/gtkinvisible.c:86 gtk/gtkmountoperation.c:155 -#: gtk/gtkstatusicon.c:277 gtk/gtkwindow.c:614 +#: gdk/gdkpango.c:538 gtk/gtkinvisible.c:86 gtk/gtkmountoperation.c:176 +#: gtk/gtkstatusicon.c:280 gtk/gtkwindow.c:614 msgid "Screen" msgstr "" -#: gdk/gdkpango.c:538 +#: gdk/gdkpango.c:539 msgid "the GdkScreen for the renderer" msgstr "" @@ -113,6 +121,10 @@ msgstr "" msgid "The resolution for fonts on the screen" msgstr "" +#: gdk/gdkwindow.c:472 gdk/gdkwindow.c:473 +msgid "Cursor" +msgstr "" + #: gtk/gtkaboutdialog.c:239 msgid "Program name" msgstr "" @@ -250,7 +262,7 @@ msgid "A unique name for the action." msgstr "" #: gtk/gtkaction.c:198 gtk/gtkbutton.c:219 gtk/gtkexpander.c:195 -#: gtk/gtkframe.c:105 gtk/gtklabel.c:495 gtk/gtkmenuitem.c:300 +#: gtk/gtkframe.c:105 gtk/gtklabel.c:496 gtk/gtkmenuitem.c:305 #: gtk/gtktoolbutton.c:202 msgid "Label" msgstr "" @@ -283,30 +295,30 @@ msgstr "" msgid "The stock icon displayed in widgets representing this action." msgstr "" -#: gtk/gtkaction.c:261 gtk/gtkstatusicon.c:250 +#: gtk/gtkaction.c:261 gtk/gtkstatusicon.c:253 msgid "GIcon" msgstr "" #: gtk/gtkaction.c:262 gtk/gtkcellrendererpixbuf.c:206 gtk/gtkimage.c:248 -#: gtk/gtkstatusicon.c:251 +#: gtk/gtkstatusicon.c:254 msgid "The GIcon being displayed" msgstr "" #: gtk/gtkaction.c:282 gtk/gtkcellrendererpixbuf.c:171 gtk/gtkimage.c:230 -#: gtk/gtkprinter.c:172 gtk/gtkstatusicon.c:234 gtk/gtkwindow.c:606 +#: gtk/gtkprinter.c:172 gtk/gtkstatusicon.c:237 gtk/gtkwindow.c:606 msgid "Icon Name" msgstr "" #: gtk/gtkaction.c:283 gtk/gtkcellrendererpixbuf.c:172 gtk/gtkimage.c:231 -#: gtk/gtkstatusicon.c:235 +#: gtk/gtkstatusicon.c:238 msgid "The name of the icon from the icon theme" msgstr "" -#: gtk/gtkaction.c:290 gtk/gtktoolitem.c:176 +#: gtk/gtkaction.c:290 gtk/gtktoolitem.c:192 msgid "Visible when horizontal" msgstr "" -#: gtk/gtkaction.c:291 gtk/gtktoolitem.c:177 +#: gtk/gtkaction.c:291 gtk/gtktoolitem.c:193 msgid "" "Whether the toolbar item is visible when the toolbar is in a horizontal " "orientation." @@ -322,17 +334,17 @@ msgid "" "overflow menu." msgstr "" -#: gtk/gtkaction.c:314 gtk/gtktoolitem.c:183 +#: gtk/gtkaction.c:314 gtk/gtktoolitem.c:199 msgid "Visible when vertical" msgstr "" -#: gtk/gtkaction.c:315 gtk/gtktoolitem.c:184 +#: gtk/gtkaction.c:315 gtk/gtktoolitem.c:200 msgid "" "Whether the toolbar item is visible when the toolbar is in a vertical " "orientation." msgstr "" -#: gtk/gtkaction.c:322 gtk/gtktoolitem.c:190 +#: gtk/gtkaction.c:322 gtk/gtktoolitem.c:206 msgid "Is important" msgstr "" @@ -351,7 +363,7 @@ msgid "When TRUE, empty menu proxies for this action are hidden." msgstr "" #: gtk/gtkaction.c:338 gtk/gtkactiongroup.c:177 gtk/gtkcellrenderer.c:193 -#: gtk/gtkwidget.c:523 +#: gtk/gtkwidget.c:525 msgid "Sensitive" msgstr "" @@ -359,8 +371,8 @@ msgstr "" msgid "Whether the action is enabled." msgstr "" -#: gtk/gtkaction.c:345 gtk/gtkactiongroup.c:184 gtk/gtkstatusicon.c:293 -#: gtk/gtktreeviewcolumn.c:191 gtk/gtkwidget.c:516 +#: gtk/gtkaction.c:345 gtk/gtkactiongroup.c:184 gtk/gtkstatusicon.c:296 +#: gtk/gtktreeviewcolumn.c:192 gtk/gtkwidget.c:518 msgid "Visible" msgstr "" @@ -390,6 +402,22 @@ msgstr "" msgid "Whether the action group is visible." msgstr "" +#: gtk/gtkactivatable.c:304 +msgid "Related Action" +msgstr "" + +#: gtk/gtkactivatable.c:305 +msgid "The action this activatable will activate and receive updates from" +msgstr "" + +#: gtk/gtkactivatable.c:327 +msgid "Use Action Appearance" +msgstr "" + +#: gtk/gtkactivatable.c:328 +msgid "Whether to use the related actions appearance properties" +msgstr "" + #: gtk/gtkadjustment.c:93 gtk/gtkcellrendererprogress.c:128 #: gtk/gtkscalebutton.c:206 gtk/gtkspinbutton.c:269 msgid "Value" @@ -527,7 +555,7 @@ msgstr "" msgid "Appearance of the shadow surrounding the arrow" msgstr "" -#: gtk/gtkarrow.c:92 gtk/gtkmenu.c:689 gtk/gtkmenuitem.c:363 +#: gtk/gtkarrow.c:92 gtk/gtkmenu.c:711 gtk/gtkmenuitem.c:368 msgid "Arrow Scaling" msgstr "" @@ -623,60 +651,60 @@ msgstr "" msgid "Whether all required fields on the page have been filled out" msgstr "" -#: gtk/gtkbbox.c:99 +#: gtk/gtkbbox.c:101 msgid "Minimum child width" msgstr "" -#: gtk/gtkbbox.c:100 +#: gtk/gtkbbox.c:102 msgid "Minimum width of buttons inside the box" msgstr "" -#: gtk/gtkbbox.c:108 +#: gtk/gtkbbox.c:110 msgid "Minimum child height" msgstr "" -#: gtk/gtkbbox.c:109 +#: gtk/gtkbbox.c:111 msgid "Minimum height of buttons inside the box" msgstr "" -#: gtk/gtkbbox.c:117 +#: gtk/gtkbbox.c:119 msgid "Child internal width padding" msgstr "" -#: gtk/gtkbbox.c:118 +#: gtk/gtkbbox.c:120 msgid "Amount to increase child's size on either side" msgstr "" -#: gtk/gtkbbox.c:126 +#: gtk/gtkbbox.c:128 msgid "Child internal height padding" msgstr "" -#: gtk/gtkbbox.c:127 +#: gtk/gtkbbox.c:129 msgid "Amount to increase child's size on the top and bottom" msgstr "" -#: gtk/gtkbbox.c:135 +#: gtk/gtkbbox.c:137 msgid "Layout style" msgstr "" -#: gtk/gtkbbox.c:136 +#: gtk/gtkbbox.c:138 msgid "" "How to layout the buttons in the box. Possible values are default, spread, " "edge, start and end" msgstr "" -#: gtk/gtkbbox.c:144 +#: gtk/gtkbbox.c:146 msgid "Secondary" msgstr "" -#: gtk/gtkbbox.c:145 +#: gtk/gtkbbox.c:147 msgid "" "If TRUE, the child appears in a secondary group of children, suitable for, e." "g., help buttons" msgstr "" -#: gtk/gtkbox.c:130 gtk/gtkexpander.c:219 gtk/gtkiconview.c:664 -#: gtk/gtktreeviewcolumn.c:216 +#: gtk/gtkbox.c:130 gtk/gtkexpander.c:219 gtk/gtkiconview.c:665 +#: gtk/gtktreeviewcolumn.c:217 msgid "Spacing" msgstr "" @@ -694,7 +722,7 @@ msgid "Whether the children should all be the same size" msgstr "" #: gtk/gtkbox.c:148 gtk/gtkpreview.c:101 gtk/gtktoolbar.c:565 -#: gtk/gtktreeviewcolumn.c:272 +#: gtk/gtktreeviewcolumn.c:273 msgid "Expand" msgstr "" @@ -753,13 +781,13 @@ msgid "" "widget" msgstr "" -#: gtk/gtkbutton.c:227 gtk/gtkexpander.c:203 gtk/gtklabel.c:516 -#: gtk/gtkmenuitem.c:315 gtk/gtktoolbutton.c:209 +#: gtk/gtkbutton.c:227 gtk/gtkexpander.c:203 gtk/gtklabel.c:517 +#: gtk/gtkmenuitem.c:320 gtk/gtktoolbutton.c:209 msgid "Use underline" msgstr "" -#: gtk/gtkbutton.c:228 gtk/gtkexpander.c:204 gtk/gtklabel.c:517 -#: gtk/gtkmenuitem.c:316 +#: gtk/gtkbutton.c:228 gtk/gtkexpander.c:204 gtk/gtklabel.c:518 +#: gtk/gtkmenuitem.c:321 msgid "" "If set, an underline in the text indicates the next character should be used " "for the mnemonic accelerator key" @@ -774,7 +802,7 @@ msgid "" "If set, the label is used to pick a stock item instead of being displayed" msgstr "" -#: gtk/gtkbutton.c:243 gtk/gtkcombobox.c:789 gtk/gtkfilechooserbutton.c:393 +#: gtk/gtkbutton.c:243 gtk/gtkcombobox.c:791 gtk/gtkfilechooserbutton.c:393 msgid "Focus on click" msgstr "" @@ -860,7 +888,7 @@ msgid "" "rectangle" msgstr "" -#: gtk/gtkbutton.c:485 gtk/gtkentry.c:658 gtk/gtkentry.c:1682 +#: gtk/gtkbutton.c:485 gtk/gtkentry.c:689 gtk/gtkentry.c:1713 msgid "Inner Border" msgstr "" @@ -1082,35 +1110,35 @@ msgstr "" msgid "Whether this tag affects the cell background color" msgstr "" -#: gtk/gtkcellrendereraccel.c:113 +#: gtk/gtkcellrendereraccel.c:114 msgid "Accelerator key" msgstr "" -#: gtk/gtkcellrendereraccel.c:114 +#: gtk/gtkcellrendereraccel.c:115 msgid "The keyval of the accelerator" msgstr "" -#: gtk/gtkcellrendereraccel.c:130 +#: gtk/gtkcellrendereraccel.c:131 msgid "Accelerator modifiers" msgstr "" -#: gtk/gtkcellrendereraccel.c:131 +#: gtk/gtkcellrendereraccel.c:132 msgid "The modifier mask of the accelerator" msgstr "" -#: gtk/gtkcellrendereraccel.c:148 +#: gtk/gtkcellrendereraccel.c:149 msgid "Accelerator keycode" msgstr "" -#: gtk/gtkcellrendereraccel.c:149 +#: gtk/gtkcellrendereraccel.c:150 msgid "The hardware keycode of the accelerator" msgstr "" -#: gtk/gtkcellrendereraccel.c:168 +#: gtk/gtkcellrendereraccel.c:169 msgid "Accelerator Mode" msgstr "" -#: gtk/gtkcellrendereraccel.c:169 +#: gtk/gtkcellrendereraccel.c:170 msgid "The type of accelerators" msgstr "" @@ -1162,7 +1190,7 @@ msgstr "" msgid "Pixbuf for closed expander" msgstr "" -#: gtk/gtkcellrendererpixbuf.c:135 gtk/gtkimage.c:172 gtk/gtkstatusicon.c:226 +#: gtk/gtkcellrendererpixbuf.c:135 gtk/gtkimage.c:172 gtk/gtkstatusicon.c:229 msgid "Stock ID" msgstr "" @@ -1171,7 +1199,7 @@ msgid "The stock ID of the stock icon to render" msgstr "" #: gtk/gtkcellrendererpixbuf.c:143 gtk/gtkrecentmanager.c:245 -#: gtk/gtkstatusicon.c:267 +#: gtk/gtkstatusicon.c:270 msgid "Size" msgstr "" @@ -1204,8 +1232,8 @@ msgid "Value of the progress bar" msgstr "" #: gtk/gtkcellrendererprogress.c:146 gtk/gtkcellrenderertext.c:195 -#: gtk/gtkentry.c:701 gtk/gtkmessagedialog.c:153 gtk/gtkprogressbar.c:184 -#: gtk/gtktextbuffer.c:198 +#: gtk/gtkentry.c:732 gtk/gtkentrybuffer.c:353 gtk/gtkmessagedialog.c:153 +#: gtk/gtkprogressbar.c:184 gtk/gtktextbuffer.c:198 msgid "Text" msgstr "" @@ -1242,7 +1270,7 @@ msgid "The vertical text alignment, from 0 (top) to 1 (bottom)." msgstr "" #: gtk/gtkcellrendererprogress.c:221 gtk/gtkiconview.c:729 -#: gtk/gtkorientable.c:74 gtk/gtkprogressbar.c:126 gtk/gtkstatusicon.c:325 +#: gtk/gtkorientable.c:74 gtk/gtkprogressbar.c:126 gtk/gtkstatusicon.c:328 #: gtk/gtktrayicon-x11.c:110 msgid "Orientation" msgstr "" @@ -1288,7 +1316,7 @@ msgstr "" msgid "Marked up text to render" msgstr "" -#: gtk/gtkcellrenderertext.c:211 gtk/gtklabel.c:502 +#: gtk/gtkcellrenderertext.c:211 gtk/gtklabel.c:503 msgid "Attributes" msgstr "" @@ -1336,12 +1364,12 @@ msgstr "" msgid "Foreground color as a GdkColor" msgstr "" -#: gtk/gtkcellrenderertext.c:261 gtk/gtkentry.c:625 gtk/gtktexttag.c:251 -#: gtk/gtktextview.c:573 +#: gtk/gtkcellrenderertext.c:261 gtk/gtkentry.c:656 gtk/gtktexttag.c:251 +#: gtk/gtktextview.c:574 msgid "Editable" msgstr "" -#: gtk/gtkcellrenderertext.c:262 gtk/gtktexttag.c:252 gtk/gtktextview.c:574 +#: gtk/gtkcellrenderertext.c:262 gtk/gtktexttag.c:252 gtk/gtktextview.c:575 msgid "Whether the text can be modified by the user" msgstr "" @@ -1443,7 +1471,7 @@ msgid "" "probably don't need it" msgstr "" -#: gtk/gtkcellrenderertext.c:411 gtk/gtklabel.c:627 gtk/gtkprogressbar.c:206 +#: gtk/gtkcellrenderertext.c:411 gtk/gtklabel.c:628 gtk/gtkprogressbar.c:206 msgid "Ellipsize" msgstr "" @@ -1454,11 +1482,11 @@ msgid "" msgstr "" #: gtk/gtkcellrenderertext.c:431 gtk/gtkfilechooserbutton.c:421 -#: gtk/gtklabel.c:647 +#: gtk/gtklabel.c:648 msgid "Width In Characters" msgstr "" -#: gtk/gtkcellrenderertext.c:432 gtk/gtklabel.c:648 +#: gtk/gtkcellrenderertext.c:432 gtk/gtklabel.c:649 msgid "The desired width of the label, in characters" msgstr "" @@ -1472,7 +1500,7 @@ msgid "" "have enough room to display the entire string" msgstr "" -#: gtk/gtkcellrenderertext.c:470 gtk/gtkcombobox.c:678 +#: gtk/gtkcellrenderertext.c:470 gtk/gtkcombobox.c:680 msgid "Wrap width" msgstr "" @@ -1480,7 +1508,7 @@ msgstr "" msgid "The width at which the text is wrapped" msgstr "" -#: gtk/gtkcellrenderertext.c:491 gtk/gtktreeviewcolumn.c:297 +#: gtk/gtkcellrenderertext.c:491 gtk/gtktreeviewcolumn.c:298 msgid "Alignment" msgstr "" @@ -1677,7 +1705,7 @@ msgstr "" msgid "Spacing around check or radio indicator" msgstr "" -#: gtk/gtkcheckmenuitem.c:98 gtk/gtkmenu.c:500 gtk/gtktoggleaction.c:119 +#: gtk/gtkcheckmenuitem.c:98 gtk/gtkmenu.c:501 gtk/gtktoggleaction.c:119 #: gtk/gtktogglebutton.c:115 gtk/gtktoggletoolbutton.c:114 msgid "Active" msgstr "" @@ -1711,7 +1739,8 @@ msgid "Whether or not to give the color an alpha value" msgstr "" #: gtk/gtkcolorbutton.c:186 gtk/gtkfilechooserbutton.c:407 -#: gtk/gtkfontbutton.c:142 gtk/gtkprintjob.c:116 gtk/gtktreeviewcolumn.c:264 +#: gtk/gtkfontbutton.c:142 gtk/gtkprintjob.c:116 gtk/gtkstatusicon.c:424 +#: gtk/gtktreeviewcolumn.c:265 msgid "Title" msgstr "" @@ -1839,111 +1868,111 @@ msgstr "" msgid "Whether entered values must already be present in the list" msgstr "" -#: gtk/gtkcombobox.c:661 +#: gtk/gtkcombobox.c:663 msgid "ComboBox model" msgstr "" -#: gtk/gtkcombobox.c:662 +#: gtk/gtkcombobox.c:664 msgid "The model for the combo box" msgstr "" -#: gtk/gtkcombobox.c:679 +#: gtk/gtkcombobox.c:681 msgid "Wrap width for laying out the items in a grid" msgstr "" -#: gtk/gtkcombobox.c:701 +#: gtk/gtkcombobox.c:703 msgid "Row span column" msgstr "" -#: gtk/gtkcombobox.c:702 +#: gtk/gtkcombobox.c:704 msgid "TreeModel column containing the row span values" msgstr "" -#: gtk/gtkcombobox.c:723 +#: gtk/gtkcombobox.c:725 msgid "Column span column" msgstr "" -#: gtk/gtkcombobox.c:724 +#: gtk/gtkcombobox.c:726 msgid "TreeModel column containing the column span values" msgstr "" -#: gtk/gtkcombobox.c:745 +#: gtk/gtkcombobox.c:747 msgid "Active item" msgstr "" -#: gtk/gtkcombobox.c:746 +#: gtk/gtkcombobox.c:748 msgid "The item which is currently active" msgstr "" -#: gtk/gtkcombobox.c:765 gtk/gtkuimanager.c:222 +#: gtk/gtkcombobox.c:767 gtk/gtkuimanager.c:222 msgid "Add tearoffs to menus" msgstr "" -#: gtk/gtkcombobox.c:766 +#: gtk/gtkcombobox.c:768 msgid "Whether dropdowns should have a tearoff menu item" msgstr "" -#: gtk/gtkcombobox.c:781 gtk/gtkentry.c:650 +#: gtk/gtkcombobox.c:783 gtk/gtkentry.c:681 msgid "Has Frame" msgstr "" -#: gtk/gtkcombobox.c:782 +#: gtk/gtkcombobox.c:784 msgid "Whether the combo box draws a frame around the child" msgstr "" -#: gtk/gtkcombobox.c:790 +#: gtk/gtkcombobox.c:792 msgid "Whether the combo box grabs focus when it is clicked with the mouse" msgstr "" -#: gtk/gtkcombobox.c:805 gtk/gtkmenu.c:555 +#: gtk/gtkcombobox.c:807 gtk/gtkmenu.c:556 msgid "Tearoff Title" msgstr "" -#: gtk/gtkcombobox.c:806 +#: gtk/gtkcombobox.c:808 msgid "" "A title that may be displayed by the window manager when the popup is torn-" "off" msgstr "" -#: gtk/gtkcombobox.c:823 +#: gtk/gtkcombobox.c:825 msgid "Popup shown" msgstr "" -#: gtk/gtkcombobox.c:824 +#: gtk/gtkcombobox.c:826 msgid "Whether the combo's dropdown is shown" msgstr "" -#: gtk/gtkcombobox.c:840 +#: gtk/gtkcombobox.c:842 msgid "Button Sensitivity" msgstr "" -#: gtk/gtkcombobox.c:841 +#: gtk/gtkcombobox.c:843 msgid "Whether the dropdown button is sensitive when the model is empty" msgstr "" -#: gtk/gtkcombobox.c:848 +#: gtk/gtkcombobox.c:850 msgid "Appears as list" msgstr "" -#: gtk/gtkcombobox.c:849 +#: gtk/gtkcombobox.c:851 msgid "Whether dropdowns should look like lists rather than menus" msgstr "" -#: gtk/gtkcombobox.c:865 +#: gtk/gtkcombobox.c:867 msgid "Arrow Size" msgstr "" -#: gtk/gtkcombobox.c:866 +#: gtk/gtkcombobox.c:868 msgid "The minimum size of the arrow in the combo box" msgstr "" -#: gtk/gtkcombobox.c:881 gtk/gtkentry.c:750 gtk/gtkhandlebox.c:174 +#: gtk/gtkcombobox.c:883 gtk/gtkentry.c:781 gtk/gtkhandlebox.c:174 #: gtk/gtkmenubar.c:194 gtk/gtkstatusbar.c:186 gtk/gtktoolbar.c:623 #: gtk/gtkviewport.c:122 msgid "Shadow type" msgstr "" -#: gtk/gtkcombobox.c:882 +#: gtk/gtkcombobox.c:884 msgid "Which kind of shadow to draw around the combo box" msgstr "" @@ -2019,7 +2048,7 @@ msgstr "" msgid "The dialog has a separator bar above its buttons" msgstr "" -#: gtk/gtkdialog.c:191 +#: gtk/gtkdialog.c:191 gtk/gtkinfobar.c:439 msgid "Content area border" msgstr "" @@ -2027,7 +2056,7 @@ msgstr "" msgid "Width of border around the main dialog area" msgstr "" -#: gtk/gtkdialog.c:209 +#: gtk/gtkdialog.c:209 gtk/gtkinfobar.c:456 msgid "Content area spacing" msgstr "" @@ -2035,15 +2064,15 @@ msgstr "" msgid "Spacing between elements of the main dialog area" msgstr "" -#: gtk/gtkdialog.c:217 +#: gtk/gtkdialog.c:217 gtk/gtkinfobar.c:472 msgid "Button spacing" msgstr "" -#: gtk/gtkdialog.c:218 +#: gtk/gtkdialog.c:218 gtk/gtkinfobar.c:473 msgid "Spacing between buttons" msgstr "" -#: gtk/gtkdialog.c:226 +#: gtk/gtkdialog.c:226 gtk/gtkinfobar.c:488 msgid "Action area border" msgstr "" @@ -2051,352 +2080,368 @@ msgstr "" msgid "Width of border around the button area at the bottom of the dialog" msgstr "" -#: gtk/gtkentry.c:605 gtk/gtklabel.c:590 +#: gtk/gtkentry.c:628 +msgid "Text Buffer" +msgstr "" + +#: gtk/gtkentry.c:629 +msgid "Text buffer object which actually stores entry text" +msgstr "" + +#: gtk/gtkentry.c:636 gtk/gtklabel.c:591 msgid "Cursor Position" msgstr "" -#: gtk/gtkentry.c:606 gtk/gtklabel.c:591 +#: gtk/gtkentry.c:637 gtk/gtklabel.c:592 msgid "The current position of the insertion cursor in chars" msgstr "" -#: gtk/gtkentry.c:615 gtk/gtklabel.c:600 +#: gtk/gtkentry.c:646 gtk/gtklabel.c:601 msgid "Selection Bound" msgstr "" -#: gtk/gtkentry.c:616 gtk/gtklabel.c:601 +#: gtk/gtkentry.c:647 gtk/gtklabel.c:602 msgid "" "The position of the opposite end of the selection from the cursor in chars" msgstr "" -#: gtk/gtkentry.c:626 +#: gtk/gtkentry.c:657 msgid "Whether the entry contents can be edited" msgstr "" -#: gtk/gtkentry.c:633 +#: gtk/gtkentry.c:664 gtk/gtkentrybuffer.c:383 msgid "Maximum length" msgstr "" -#: gtk/gtkentry.c:634 +#: gtk/gtkentry.c:665 gtk/gtkentrybuffer.c:384 msgid "Maximum number of characters for this entry. Zero if no maximum" msgstr "" -#: gtk/gtkentry.c:642 +#: gtk/gtkentry.c:673 msgid "Visibility" msgstr "" -#: gtk/gtkentry.c:643 +#: gtk/gtkentry.c:674 msgid "" "FALSE displays the \"invisible char\" instead of the actual text (password " "mode)" msgstr "" -#: gtk/gtkentry.c:651 +#: gtk/gtkentry.c:682 msgid "FALSE removes outside bevel from entry" msgstr "" -#: gtk/gtkentry.c:659 +#: gtk/gtkentry.c:690 msgid "" "Border between text and frame. Overrides the inner-border style property" msgstr "" -#: gtk/gtkentry.c:666 gtk/gtkentry.c:1232 +#: gtk/gtkentry.c:697 gtk/gtkentry.c:1263 msgid "Invisible character" msgstr "" -#: gtk/gtkentry.c:667 gtk/gtkentry.c:1233 +#: gtk/gtkentry.c:698 gtk/gtkentry.c:1264 msgid "The character to use when masking entry contents (in \"password mode\")" msgstr "" -#: gtk/gtkentry.c:674 +#: gtk/gtkentry.c:705 msgid "Activates default" msgstr "" -#: gtk/gtkentry.c:675 +#: gtk/gtkentry.c:706 msgid "" "Whether to activate the default widget (such as the default button in a " "dialog) when Enter is pressed" msgstr "" -#: gtk/gtkentry.c:681 +#: gtk/gtkentry.c:712 msgid "Width in chars" msgstr "" -#: gtk/gtkentry.c:682 +#: gtk/gtkentry.c:713 msgid "Number of characters to leave space for in the entry" msgstr "" -#: gtk/gtkentry.c:691 +#: gtk/gtkentry.c:722 msgid "Scroll offset" msgstr "" -#: gtk/gtkentry.c:692 +#: gtk/gtkentry.c:723 msgid "Number of pixels of the entry scrolled off the screen to the left" msgstr "" -#: gtk/gtkentry.c:702 +#: gtk/gtkentry.c:733 msgid "The contents of the entry" msgstr "" -#: gtk/gtkentry.c:717 gtk/gtkmisc.c:73 +#: gtk/gtkentry.c:748 gtk/gtkmisc.c:73 msgid "X align" msgstr "" -#: gtk/gtkentry.c:718 gtk/gtkmisc.c:74 +#: gtk/gtkentry.c:749 gtk/gtkmisc.c:74 msgid "" "The horizontal alignment, from 0 (left) to 1 (right). Reversed for RTL " "layouts." msgstr "" -#: gtk/gtkentry.c:734 +#: gtk/gtkentry.c:765 msgid "Truncate multiline" msgstr "" -#: gtk/gtkentry.c:735 +#: gtk/gtkentry.c:766 msgid "Whether to truncate multiline pastes to one line." msgstr "" -#: gtk/gtkentry.c:751 +#: gtk/gtkentry.c:782 msgid "Which kind of shadow to draw around the entry when has-frame is set" msgstr "" -#: gtk/gtkentry.c:766 gtk/gtktextview.c:653 +#: gtk/gtkentry.c:797 gtk/gtktextview.c:654 msgid "Overwrite mode" msgstr "" -#: gtk/gtkentry.c:767 +#: gtk/gtkentry.c:798 msgid "Whether new text overwrites existing text" msgstr "" -#: gtk/gtkentry.c:781 +#: gtk/gtkentry.c:812 gtk/gtkentrybuffer.c:368 msgid "Text length" msgstr "" -#: gtk/gtkentry.c:782 +#: gtk/gtkentry.c:813 msgid "Length of the text currently in the entry" msgstr "" -#: gtk/gtkentry.c:797 +#: gtk/gtkentry.c:828 msgid "Invisible char set" msgstr "" -#: gtk/gtkentry.c:798 +#: gtk/gtkentry.c:829 msgid "Whether the invisible char has been set" msgstr "" -#: gtk/gtkentry.c:816 +#: gtk/gtkentry.c:847 msgid "Caps Lock warning" msgstr "" -#: gtk/gtkentry.c:817 +#: gtk/gtkentry.c:848 msgid "Whether password entries will show a warning when Caps Lock is on" msgstr "" -#: gtk/gtkentry.c:831 +#: gtk/gtkentry.c:862 msgid "Progress Fraction" msgstr "" -#: gtk/gtkentry.c:832 +#: gtk/gtkentry.c:863 msgid "The current fraction of the task that's been completed" msgstr "" -#: gtk/gtkentry.c:849 +#: gtk/gtkentry.c:880 msgid "Progress Pulse Step" msgstr "" -#: gtk/gtkentry.c:850 +#: gtk/gtkentry.c:881 msgid "" "The fraction of total entry width to move the progress bouncing block for " "each call to gtk_entry_progress_pulse()" msgstr "" -#: gtk/gtkentry.c:866 +#: gtk/gtkentry.c:897 msgid "Primary pixbuf" msgstr "" -#: gtk/gtkentry.c:867 +#: gtk/gtkentry.c:898 msgid "Primary pixbuf for the entry" msgstr "" -#: gtk/gtkentry.c:881 +#: gtk/gtkentry.c:912 msgid "Secondary pixbuf" msgstr "" -#: gtk/gtkentry.c:882 +#: gtk/gtkentry.c:913 msgid "Secondary pixbuf for the entry" msgstr "" -#: gtk/gtkentry.c:896 +#: gtk/gtkentry.c:927 msgid "Primary stock ID" msgstr "" -#: gtk/gtkentry.c:897 +#: gtk/gtkentry.c:928 msgid "Stock ID for primary icon" msgstr "" -#: gtk/gtkentry.c:911 +#: gtk/gtkentry.c:942 msgid "Secondary stock ID" msgstr "" -#: gtk/gtkentry.c:912 +#: gtk/gtkentry.c:943 msgid "Stock ID for secondary icon" msgstr "" -#: gtk/gtkentry.c:926 +#: gtk/gtkentry.c:957 msgid "Primary icon name" msgstr "" -#: gtk/gtkentry.c:927 +#: gtk/gtkentry.c:958 msgid "Icon name for primary icon" msgstr "" -#: gtk/gtkentry.c:941 +#: gtk/gtkentry.c:972 msgid "Secondary icon name" msgstr "" -#: gtk/gtkentry.c:942 +#: gtk/gtkentry.c:973 msgid "Icon name for secondary icon" msgstr "" -#: gtk/gtkentry.c:956 +#: gtk/gtkentry.c:987 msgid "Primary GIcon" msgstr "" -#: gtk/gtkentry.c:957 +#: gtk/gtkentry.c:988 msgid "GIcon for primary icon" msgstr "" -#: gtk/gtkentry.c:971 +#: gtk/gtkentry.c:1002 msgid "Secondary GIcon" msgstr "" -#: gtk/gtkentry.c:972 +#: gtk/gtkentry.c:1003 msgid "GIcon for secondary icon" msgstr "" -#: gtk/gtkentry.c:986 +#: gtk/gtkentry.c:1017 msgid "Primary storage type" msgstr "" -#: gtk/gtkentry.c:987 +#: gtk/gtkentry.c:1018 msgid "The representation being used for primary icon" msgstr "" -#: gtk/gtkentry.c:1002 +#: gtk/gtkentry.c:1033 msgid "Secondary storage type" msgstr "" -#: gtk/gtkentry.c:1003 +#: gtk/gtkentry.c:1034 msgid "The representation being used for secondary icon" msgstr "" -#: gtk/gtkentry.c:1024 +#: gtk/gtkentry.c:1055 msgid "Primary icon activatable" msgstr "" -#: gtk/gtkentry.c:1025 +#: gtk/gtkentry.c:1056 msgid "Whether the primary icon is activatable" msgstr "" -#: gtk/gtkentry.c:1045 +#: gtk/gtkentry.c:1076 msgid "Secondary icon activatable" msgstr "" -#: gtk/gtkentry.c:1046 +#: gtk/gtkentry.c:1077 msgid "Whether the secondary icon is activatable" msgstr "" -#: gtk/gtkentry.c:1068 +#: gtk/gtkentry.c:1099 msgid "Primary icon sensitive" msgstr "" -#: gtk/gtkentry.c:1069 +#: gtk/gtkentry.c:1100 msgid "Whether the primary icon is sensitive" msgstr "" -#: gtk/gtkentry.c:1090 +#: gtk/gtkentry.c:1121 msgid "Secondary icon sensitive" msgstr "" -#: gtk/gtkentry.c:1091 +#: gtk/gtkentry.c:1122 msgid "Whether the secondary icon is sensitive" msgstr "" -#: gtk/gtkentry.c:1107 +#: gtk/gtkentry.c:1138 msgid "Primary icon tooltip text" msgstr "" -#: gtk/gtkentry.c:1108 gtk/gtkentry.c:1144 +#: gtk/gtkentry.c:1139 gtk/gtkentry.c:1175 msgid "The contents of the tooltip on the primary icon" msgstr "" -#: gtk/gtkentry.c:1124 +#: gtk/gtkentry.c:1155 msgid "Secondary icon tooltip text" msgstr "" -#: gtk/gtkentry.c:1125 gtk/gtkentry.c:1163 +#: gtk/gtkentry.c:1156 gtk/gtkentry.c:1194 msgid "The contents of the tooltip on the secondary icon" msgstr "" -#: gtk/gtkentry.c:1143 +#: gtk/gtkentry.c:1174 msgid "Primary icon tooltip markup" msgstr "" -#: gtk/gtkentry.c:1162 +#: gtk/gtkentry.c:1193 msgid "Secondary icon tooltip markup" msgstr "" -#: gtk/gtkentry.c:1182 gtk/gtktextview.c:681 +#: gtk/gtkentry.c:1213 gtk/gtktextview.c:682 msgid "IM module" msgstr "" -#: gtk/gtkentry.c:1183 gtk/gtktextview.c:682 +#: gtk/gtkentry.c:1214 gtk/gtktextview.c:683 msgid "Which IM module should be used" msgstr "" -#: gtk/gtkentry.c:1197 +#: gtk/gtkentry.c:1228 msgid "Icon Prelight" msgstr "" -#: gtk/gtkentry.c:1198 +#: gtk/gtkentry.c:1229 msgid "Whether activatable icons should prelight when hovered" msgstr "" -#: gtk/gtkentry.c:1211 +#: gtk/gtkentry.c:1242 msgid "Progress Border" msgstr "" -#: gtk/gtkentry.c:1212 +#: gtk/gtkentry.c:1243 msgid "Border around the progress bar" msgstr "" -#: gtk/gtkentry.c:1683 +#: gtk/gtkentry.c:1714 msgid "Border between text and frame." msgstr "" -#: gtk/gtkentry.c:1697 +#: gtk/gtkentry.c:1728 msgid "State Hint" msgstr "" -#: gtk/gtkentry.c:1698 +#: gtk/gtkentry.c:1729 msgid "Whether to pass a proper state when drawing shadow or background" msgstr "" -#: gtk/gtkentry.c:1703 gtk/gtklabel.c:830 +#: gtk/gtkentry.c:1734 gtk/gtklabel.c:848 msgid "Select on focus" msgstr "" -#: gtk/gtkentry.c:1704 +#: gtk/gtkentry.c:1735 msgid "Whether to select the contents of an entry when it is focused" msgstr "" -#: gtk/gtkentry.c:1718 +#: gtk/gtkentry.c:1749 msgid "Password Hint Timeout" msgstr "" -#: gtk/gtkentry.c:1719 +#: gtk/gtkentry.c:1750 msgid "How long to show the last input character in hidden entries" msgstr "" +#: gtk/gtkentrybuffer.c:354 +msgid "The contents of the buffer" +msgstr "" + +#: gtk/gtkentrybuffer.c:369 +msgid "Length of the text currently in the buffer" +msgstr "" + #: gtk/gtkentrycompletion.c:279 msgid "Completion Model" msgstr "" @@ -2413,7 +2458,7 @@ msgstr "" msgid "Minimum length of the search key in order to look up matches" msgstr "" -#: gtk/gtkentrycompletion.c:303 gtk/gtkiconview.c:585 +#: gtk/gtkentrycompletion.c:303 gtk/gtkiconview.c:586 msgid "Text column" msgstr "" @@ -2493,11 +2538,11 @@ msgstr "" msgid "Text of the expander's label" msgstr "" -#: gtk/gtkexpander.c:211 gtk/gtklabel.c:509 +#: gtk/gtkexpander.c:211 gtk/gtklabel.c:510 msgid "Use markup" msgstr "" -#: gtk/gtkexpander.c:212 gtk/gtklabel.c:510 +#: gtk/gtkexpander.c:212 gtk/gtklabel.c:511 msgid "The text of the label includes XML markup. See pango_parse_markup()" msgstr "" @@ -2513,11 +2558,11 @@ msgstr "" msgid "A widget to display in place of the usual expander label" msgstr "" -#: gtk/gtkexpander.c:236 gtk/gtktreeview.c:783 +#: gtk/gtkexpander.c:236 gtk/gtktreeview.c:774 msgid "Expander Size" msgstr "" -#: gtk/gtkexpander.c:237 gtk/gtktreeview.c:784 +#: gtk/gtkexpander.c:237 gtk/gtktreeview.c:775 msgid "Size of the expander arrow" msgstr "" @@ -2616,6 +2661,16 @@ msgid "" "dialog if necessary." msgstr "" +#: gtk/gtkfilechooser.c:283 +msgid "Allow folders creation" +msgstr "" + +#: gtk/gtkfilechooser.c:284 +msgid "" +"Whether a file chooser not in open mode will offer the user to create new " +"folders." +msgstr "" + #: gtk/gtkfilechooserbutton.c:376 msgid "Dialog" msgstr "" @@ -2633,7 +2688,7 @@ msgid "The desired width of the button widget, in characters." msgstr "" #: gtk/gtkfilesel.c:526 gtk/gtkimage.c:163 gtk/gtkrecentmanager.c:214 -#: gtk/gtkstatusicon.c:218 +#: gtk/gtkstatusicon.c:221 msgid "Filename" msgstr "" @@ -2807,83 +2862,83 @@ msgid "" "detached." msgstr "" -#: gtk/gtkiconview.c:548 +#: gtk/gtkiconview.c:549 msgid "Selection mode" msgstr "" -#: gtk/gtkiconview.c:549 +#: gtk/gtkiconview.c:550 msgid "The selection mode" msgstr "" -#: gtk/gtkiconview.c:567 +#: gtk/gtkiconview.c:568 msgid "Pixbuf column" msgstr "" -#: gtk/gtkiconview.c:568 +#: gtk/gtkiconview.c:569 msgid "Model column used to retrieve the icon pixbuf from" msgstr "" -#: gtk/gtkiconview.c:586 +#: gtk/gtkiconview.c:587 msgid "Model column used to retrieve the text from" msgstr "" -#: gtk/gtkiconview.c:605 +#: gtk/gtkiconview.c:606 msgid "Markup column" msgstr "" -#: gtk/gtkiconview.c:606 +#: gtk/gtkiconview.c:607 msgid "Model column used to retrieve the text if using Pango markup" msgstr "" -#: gtk/gtkiconview.c:613 +#: gtk/gtkiconview.c:614 msgid "Icon View Model" msgstr "" -#: gtk/gtkiconview.c:614 +#: gtk/gtkiconview.c:615 msgid "The model for the icon view" msgstr "" -#: gtk/gtkiconview.c:630 +#: gtk/gtkiconview.c:631 msgid "Number of columns" msgstr "" -#: gtk/gtkiconview.c:631 +#: gtk/gtkiconview.c:632 msgid "Number of columns to display" msgstr "" -#: gtk/gtkiconview.c:648 +#: gtk/gtkiconview.c:649 msgid "Width for each item" msgstr "" -#: gtk/gtkiconview.c:649 +#: gtk/gtkiconview.c:650 msgid "The width used for each item" msgstr "" -#: gtk/gtkiconview.c:665 +#: gtk/gtkiconview.c:666 msgid "Space which is inserted between cells of an item" msgstr "" -#: gtk/gtkiconview.c:680 +#: gtk/gtkiconview.c:681 msgid "Row Spacing" msgstr "" -#: gtk/gtkiconview.c:681 +#: gtk/gtkiconview.c:682 msgid "Space which is inserted between grid rows" msgstr "" -#: gtk/gtkiconview.c:696 +#: gtk/gtkiconview.c:697 msgid "Column Spacing" msgstr "" -#: gtk/gtkiconview.c:697 +#: gtk/gtkiconview.c:698 msgid "Space which is inserted between grid columns" msgstr "" -#: gtk/gtkiconview.c:712 +#: gtk/gtkiconview.c:713 msgid "Margin" msgstr "" -#: gtk/gtkiconview.c:713 +#: gtk/gtkiconview.c:714 msgid "Space which is inserted at the edges of the icon view" msgstr "" @@ -2892,15 +2947,15 @@ msgid "" "How the text and icon of each item are positioned relative to each other" msgstr "" -#: gtk/gtkiconview.c:746 gtk/gtktreeview.c:618 gtk/gtktreeviewcolumn.c:307 +#: gtk/gtkiconview.c:746 gtk/gtktreeview.c:609 gtk/gtktreeviewcolumn.c:308 msgid "Reorderable" msgstr "" -#: gtk/gtkiconview.c:747 gtk/gtktreeview.c:619 +#: gtk/gtkiconview.c:747 gtk/gtktreeview.c:610 msgid "View is reorderable" msgstr "" -#: gtk/gtkiconview.c:754 gtk/gtktreeview.c:769 +#: gtk/gtkiconview.c:754 gtk/gtktreeview.c:760 msgid "Tooltip Column" msgstr "" @@ -2908,27 +2963,35 @@ msgstr "" msgid "The column in the model containing the tooltip texts for the items" msgstr "" -#: gtk/gtkiconview.c:766 -msgid "Selection Box Color" -msgstr "" - -#: gtk/gtkiconview.c:767 -msgid "Color of the selection box" +#: gtk/gtkiconview.c:772 +msgid "Item Padding" msgstr "" #: gtk/gtkiconview.c:773 +msgid "Padding around icon view items" +msgstr "" + +#: gtk/gtkiconview.c:782 +msgid "Selection Box Color" +msgstr "" + +#: gtk/gtkiconview.c:783 +msgid "Color of the selection box" +msgstr "" + +#: gtk/gtkiconview.c:789 msgid "Selection Box Alpha" msgstr "" -#: gtk/gtkiconview.c:774 +#: gtk/gtkiconview.c:790 msgid "Opacity of the selection box" msgstr "" -#: gtk/gtkimage.c:131 gtk/gtkstatusicon.c:210 +#: gtk/gtkimage.c:131 gtk/gtkstatusicon.c:213 msgid "Pixbuf" msgstr "" -#: gtk/gtkimage.c:132 gtk/gtkstatusicon.c:211 +#: gtk/gtkimage.c:132 gtk/gtkstatusicon.c:214 msgid "A GdkPixbuf to display" msgstr "" @@ -2956,11 +3019,11 @@ msgstr "" msgid "Mask bitmap to use with GdkImage or GdkPixmap" msgstr "" -#: gtk/gtkimage.c:164 gtk/gtkstatusicon.c:219 +#: gtk/gtkimage.c:164 gtk/gtkstatusicon.c:222 msgid "Filename to load and display" msgstr "" -#: gtk/gtkimage.c:173 gtk/gtkstatusicon.c:227 +#: gtk/gtkimage.c:173 gtk/gtkstatusicon.c:230 msgid "Stock ID for a stock image to display" msgstr "" @@ -2996,11 +3059,11 @@ msgstr "" msgid "GdkPixbufAnimation to display" msgstr "" -#: gtk/gtkimage.c:255 gtk/gtkstatusicon.c:258 +#: gtk/gtkimage.c:255 gtk/gtkstatusicon.c:261 msgid "Storage type" msgstr "" -#: gtk/gtkimage.c:256 gtk/gtkstatusicon.c:259 +#: gtk/gtkimage.c:256 gtk/gtkstatusicon.c:262 msgid "The representation being used for image data" msgstr "" @@ -3020,7 +3083,7 @@ msgstr "" msgid "Whether the image will always be shown" msgstr "" -#: gtk/gtkimagemenuitem.c:184 gtk/gtkmenu.c:515 +#: gtk/gtkimagemenuitem.c:184 gtk/gtkmenu.c:516 msgid "Accel Group" msgstr "" @@ -3036,110 +3099,138 @@ msgstr "" msgid "Whether images should be shown in menus" msgstr "" +#: gtk/gtkinfobar.c:384 gtk/gtkmessagedialog.c:128 +msgid "Message Type" +msgstr "" + +#: gtk/gtkinfobar.c:385 gtk/gtkmessagedialog.c:129 +msgid "The type of message" +msgstr "" + +#: gtk/gtkinfobar.c:440 +msgid "Width of border around the content area" +msgstr "" + +#: gtk/gtkinfobar.c:457 +msgid "Spacing between elements of the area" +msgstr "" + +#: gtk/gtkinfobar.c:489 +msgid "Width of border around the action area" +msgstr "" + #: gtk/gtkinvisible.c:87 gtk/gtkwindow.c:615 msgid "The screen where this window will be displayed" msgstr "" -#: gtk/gtklabel.c:496 +#: gtk/gtklabel.c:497 msgid "The text of the label" msgstr "" -#: gtk/gtklabel.c:503 +#: gtk/gtklabel.c:504 msgid "A list of style attributes to apply to the text of the label" msgstr "" -#: gtk/gtklabel.c:524 gtk/gtktexttag.c:359 gtk/gtktextview.c:590 +#: gtk/gtklabel.c:525 gtk/gtktexttag.c:359 gtk/gtktextview.c:591 msgid "Justification" msgstr "" -#: gtk/gtklabel.c:525 +#: gtk/gtklabel.c:526 msgid "" "The alignment of the lines in the text of the label relative to each other. " "This does NOT affect the alignment of the label within its allocation. See " "GtkMisc::xalign for that" msgstr "" -#: gtk/gtklabel.c:533 +#: gtk/gtklabel.c:534 msgid "Pattern" msgstr "" -#: gtk/gtklabel.c:534 +#: gtk/gtklabel.c:535 msgid "" "A string with _ characters in positions correspond to characters in the text " "to underline" msgstr "" -#: gtk/gtklabel.c:541 +#: gtk/gtklabel.c:542 msgid "Line wrap" msgstr "" -#: gtk/gtklabel.c:542 +#: gtk/gtklabel.c:543 msgid "If set, wrap lines if the text becomes too wide" msgstr "" -#: gtk/gtklabel.c:557 +#: gtk/gtklabel.c:558 msgid "Line wrap mode" msgstr "" -#: gtk/gtklabel.c:558 +#: gtk/gtklabel.c:559 msgid "If wrap is set, controls how linewrapping is done" msgstr "" -#: gtk/gtklabel.c:565 +#: gtk/gtklabel.c:566 msgid "Selectable" msgstr "" -#: gtk/gtklabel.c:566 +#: gtk/gtklabel.c:567 msgid "Whether the label text can be selected with the mouse" msgstr "" -#: gtk/gtklabel.c:572 +#: gtk/gtklabel.c:573 msgid "Mnemonic key" msgstr "" -#: gtk/gtklabel.c:573 +#: gtk/gtklabel.c:574 msgid "The mnemonic accelerator key for this label" msgstr "" -#: gtk/gtklabel.c:581 +#: gtk/gtklabel.c:582 msgid "Mnemonic widget" msgstr "" -#: gtk/gtklabel.c:582 +#: gtk/gtklabel.c:583 msgid "The widget to be activated when the label's mnemonic key is pressed" msgstr "" -#: gtk/gtklabel.c:628 +#: gtk/gtklabel.c:629 msgid "" "The preferred place to ellipsize the string, if the label does not have " "enough room to display the entire string" msgstr "" -#: gtk/gtklabel.c:668 +#: gtk/gtklabel.c:669 msgid "Single Line Mode" msgstr "" -#: gtk/gtklabel.c:669 +#: gtk/gtklabel.c:670 msgid "Whether the label is in single line mode" msgstr "" -#: gtk/gtklabel.c:686 +#: gtk/gtklabel.c:687 msgid "Angle" msgstr "" -#: gtk/gtklabel.c:687 +#: gtk/gtklabel.c:688 msgid "Angle at which the label is rotated" msgstr "" -#: gtk/gtklabel.c:707 +#: gtk/gtklabel.c:708 msgid "Maximum Width In Characters" msgstr "" -#: gtk/gtklabel.c:708 +#: gtk/gtklabel.c:709 msgid "The desired maximum width of the label, in characters" msgstr "" -#: gtk/gtklabel.c:831 +#: gtk/gtklabel.c:727 +msgid "Track visited links" +msgstr "" + +#: gtk/gtklabel.c:728 +msgid "Whether visited links should be tracked" +msgstr "" + +#: gtk/gtklabel.c:849 msgid "Whether to select the contents of a selectable label when it is focused" msgstr "" @@ -3183,163 +3274,173 @@ msgstr "" msgid "Whether this link has been visited." msgstr "" -#: gtk/gtkmenu.c:501 +#: gtk/gtkmenu.c:502 msgid "The currently selected menu item" msgstr "" -#: gtk/gtkmenu.c:516 +#: gtk/gtkmenu.c:517 msgid "The accel group holding accelerators for the menu" msgstr "" -#: gtk/gtkmenu.c:530 gtk/gtkmenuitem.c:285 +#: gtk/gtkmenu.c:531 gtk/gtkmenuitem.c:290 msgid "Accel Path" msgstr "" -#: gtk/gtkmenu.c:531 +#: gtk/gtkmenu.c:532 msgid "An accel path used to conveniently construct accel paths of child items" msgstr "" -#: gtk/gtkmenu.c:547 +#: gtk/gtkmenu.c:548 msgid "Attach Widget" msgstr "" -#: gtk/gtkmenu.c:548 +#: gtk/gtkmenu.c:549 msgid "The widget the menu is attached to" msgstr "" -#: gtk/gtkmenu.c:556 +#: gtk/gtkmenu.c:557 msgid "" "A title that may be displayed by the window manager when this menu is torn-" "off" msgstr "" -#: gtk/gtkmenu.c:570 +#: gtk/gtkmenu.c:571 msgid "Tearoff State" msgstr "" -#: gtk/gtkmenu.c:571 +#: gtk/gtkmenu.c:572 msgid "A boolean that indicates whether the menu is torn-off" msgstr "" -#: gtk/gtkmenu.c:585 +#: gtk/gtkmenu.c:586 msgid "Monitor" msgstr "" -#: gtk/gtkmenu.c:586 +#: gtk/gtkmenu.c:587 msgid "The monitor the menu will be popped up on" msgstr "" -#: gtk/gtkmenu.c:592 +#: gtk/gtkmenu.c:593 msgid "Vertical Padding" msgstr "" -#: gtk/gtkmenu.c:593 +#: gtk/gtkmenu.c:594 msgid "Extra space at the top and bottom of the menu" msgstr "" -#: gtk/gtkmenu.c:601 +#: gtk/gtkmenu.c:616 +msgid "Reserve Toggle Size" +msgstr "" + +#: gtk/gtkmenu.c:617 +msgid "" +"A boolean that indicates whether the menu reserves space for toggles and " +"icons" +msgstr "" + +#: gtk/gtkmenu.c:623 msgid "Horizontal Padding" msgstr "" -#: gtk/gtkmenu.c:602 +#: gtk/gtkmenu.c:624 msgid "Extra space at the left and right edges of the menu" msgstr "" -#: gtk/gtkmenu.c:610 +#: gtk/gtkmenu.c:632 msgid "Vertical Offset" msgstr "" -#: gtk/gtkmenu.c:611 +#: gtk/gtkmenu.c:633 msgid "" "When the menu is a submenu, position it this number of pixels offset " "vertically" msgstr "" -#: gtk/gtkmenu.c:619 +#: gtk/gtkmenu.c:641 msgid "Horizontal Offset" msgstr "" -#: gtk/gtkmenu.c:620 +#: gtk/gtkmenu.c:642 msgid "" "When the menu is a submenu, position it this number of pixels offset " "horizontally" msgstr "" -#: gtk/gtkmenu.c:628 +#: gtk/gtkmenu.c:650 msgid "Double Arrows" msgstr "" -#: gtk/gtkmenu.c:629 +#: gtk/gtkmenu.c:651 msgid "When scrolling, always show both arrows." msgstr "" -#: gtk/gtkmenu.c:642 +#: gtk/gtkmenu.c:664 msgid "Arrow Placement" msgstr "" -#: gtk/gtkmenu.c:643 +#: gtk/gtkmenu.c:665 msgid "Indicates where scroll arrows should be placed" msgstr "" -#: gtk/gtkmenu.c:651 +#: gtk/gtkmenu.c:673 msgid "Left Attach" msgstr "" -#: gtk/gtkmenu.c:652 gtk/gtktable.c:174 +#: gtk/gtkmenu.c:674 gtk/gtktable.c:174 msgid "The column number to attach the left side of the child to" msgstr "" -#: gtk/gtkmenu.c:659 +#: gtk/gtkmenu.c:681 msgid "Right Attach" msgstr "" -#: gtk/gtkmenu.c:660 +#: gtk/gtkmenu.c:682 msgid "The column number to attach the right side of the child to" msgstr "" -#: gtk/gtkmenu.c:667 +#: gtk/gtkmenu.c:689 msgid "Top Attach" msgstr "" -#: gtk/gtkmenu.c:668 +#: gtk/gtkmenu.c:690 msgid "The row number to attach the top of the child to" msgstr "" -#: gtk/gtkmenu.c:675 +#: gtk/gtkmenu.c:697 msgid "Bottom Attach" msgstr "" -#: gtk/gtkmenu.c:676 gtk/gtktable.c:195 +#: gtk/gtkmenu.c:698 gtk/gtktable.c:195 msgid "The row number to attach the bottom of the child to" msgstr "" -#: gtk/gtkmenu.c:690 +#: gtk/gtkmenu.c:712 msgid "Arbitrary constant to scale down the size of the scroll arrow" msgstr "" -#: gtk/gtkmenu.c:777 +#: gtk/gtkmenu.c:799 msgid "Can change accelerators" msgstr "" -#: gtk/gtkmenu.c:778 +#: gtk/gtkmenu.c:800 msgid "" "Whether menu accelerators can be changed by pressing a key over the menu item" msgstr "" -#: gtk/gtkmenu.c:783 +#: gtk/gtkmenu.c:805 msgid "Delay before submenus appear" msgstr "" -#: gtk/gtkmenu.c:784 +#: gtk/gtkmenu.c:806 msgid "" "Minimum time the pointer must stay over a menu item before the submenu appear" msgstr "" -#: gtk/gtkmenu.c:791 +#: gtk/gtkmenu.c:813 msgid "Delay before hiding a submenu" msgstr "" -#: gtk/gtkmenu.c:792 +#: gtk/gtkmenu.c:814 msgid "" "The time before hiding a submenu when the pointer is moving towards the " "submenu" @@ -3381,40 +3482,40 @@ msgstr "" msgid "Delay before the submenus of a menu bar appear" msgstr "" -#: gtk/gtkmenuitem.c:252 +#: gtk/gtkmenuitem.c:257 msgid "Right Justified" msgstr "" -#: gtk/gtkmenuitem.c:253 +#: gtk/gtkmenuitem.c:258 msgid "" "Sets whether the menu item appears justified at the right side of a menu bar" msgstr "" -#: gtk/gtkmenuitem.c:267 +#: gtk/gtkmenuitem.c:272 msgid "Submenu" msgstr "" -#: gtk/gtkmenuitem.c:268 +#: gtk/gtkmenuitem.c:273 msgid "The submenu attached to the menu item, or NULL if it has none" msgstr "" -#: gtk/gtkmenuitem.c:286 +#: gtk/gtkmenuitem.c:291 msgid "Sets the accelerator path of the menu item" msgstr "" -#: gtk/gtkmenuitem.c:301 +#: gtk/gtkmenuitem.c:306 msgid "The text for the child label" msgstr "" -#: gtk/gtkmenuitem.c:364 +#: gtk/gtkmenuitem.c:369 msgid "Amount of space used up by arrow, relative to the menu item's font size" msgstr "" -#: gtk/gtkmenuitem.c:377 +#: gtk/gtkmenuitem.c:382 msgid "Width in Characters" msgstr "" -#: gtk/gtkmenuitem.c:378 +#: gtk/gtkmenuitem.c:383 msgid "The minimum desired width of the menu item in characters" msgstr "" @@ -3451,14 +3552,6 @@ msgid "" "Whether to put a separator between the message dialog's text and the buttons" msgstr "" -#: gtk/gtkmessagedialog.c:128 -msgid "Message Type" -msgstr "" - -#: gtk/gtkmessagedialog.c:129 -msgid "The type of message" -msgstr "" - #: gtk/gtkmessagedialog.c:136 msgid "Message Buttons" msgstr "" @@ -3525,23 +3618,23 @@ msgid "" "The amount of space to add on the top and bottom of the widget, in pixels" msgstr "" -#: gtk/gtkmountoperation.c:139 +#: gtk/gtkmountoperation.c:160 msgid "Parent" msgstr "" -#: gtk/gtkmountoperation.c:140 +#: gtk/gtkmountoperation.c:161 msgid "The parent window" msgstr "" -#: gtk/gtkmountoperation.c:147 +#: gtk/gtkmountoperation.c:168 msgid "Is Showing" msgstr "" -#: gtk/gtkmountoperation.c:148 +#: gtk/gtkmountoperation.c:169 msgid "Are we showing a dialog" msgstr "" -#: gtk/gtkmountoperation.c:156 +#: gtk/gtkmountoperation.c:177 msgid "The screen where this window will be displayed." msgstr "" @@ -3827,7 +3920,7 @@ msgstr "" msgid "If TRUE, the child can be made smaller than its requisition" msgstr "" -#: gtk/gtkplug.c:150 gtk/gtkstatusicon.c:309 +#: gtk/gtkplug.c:150 gtk/gtkstatusicon.c:312 msgid "Embedded" msgstr "" @@ -3956,11 +4049,11 @@ msgstr "" msgid "Printer settings" msgstr "" -#: gtk/gtkprintjob.c:143 gtk/gtkprintjob.c:144 gtk/gtkprintunixdialog.c:266 +#: gtk/gtkprintjob.c:143 gtk/gtkprintjob.c:144 gtk/gtkprintunixdialog.c:302 msgid "Page Setup" msgstr "" -#: gtk/gtkprintjob.c:152 gtk/gtkprintoperation.c:1056 +#: gtk/gtkprintjob.c:152 gtk/gtkprintoperation.c:1082 msgid "Track Print Status" msgstr "" @@ -3970,158 +4063,178 @@ msgid "" "print data has been sent to the printer or print server." msgstr "" -#: gtk/gtkprintoperation.c:928 +#: gtk/gtkprintoperation.c:954 msgid "Default Page Setup" msgstr "" -#: gtk/gtkprintoperation.c:929 +#: gtk/gtkprintoperation.c:955 msgid "The GtkPageSetup used by default" msgstr "" -#: gtk/gtkprintoperation.c:947 gtk/gtkprintunixdialog.c:284 +#: gtk/gtkprintoperation.c:973 gtk/gtkprintunixdialog.c:320 msgid "Print Settings" msgstr "" -#: gtk/gtkprintoperation.c:948 gtk/gtkprintunixdialog.c:285 +#: gtk/gtkprintoperation.c:974 gtk/gtkprintunixdialog.c:321 msgid "The GtkPrintSettings used for initializing the dialog" msgstr "" -#: gtk/gtkprintoperation.c:966 +#: gtk/gtkprintoperation.c:992 msgid "Job Name" msgstr "" -#: gtk/gtkprintoperation.c:967 +#: gtk/gtkprintoperation.c:993 msgid "A string used for identifying the print job." msgstr "" -#: gtk/gtkprintoperation.c:991 +#: gtk/gtkprintoperation.c:1017 msgid "Number of Pages" msgstr "" -#: gtk/gtkprintoperation.c:992 +#: gtk/gtkprintoperation.c:1018 msgid "The number of pages in the document." msgstr "" -#: gtk/gtkprintoperation.c:1013 gtk/gtkprintunixdialog.c:274 +#: gtk/gtkprintoperation.c:1039 gtk/gtkprintunixdialog.c:310 msgid "Current Page" msgstr "" -#: gtk/gtkprintoperation.c:1014 gtk/gtkprintunixdialog.c:275 +#: gtk/gtkprintoperation.c:1040 gtk/gtkprintunixdialog.c:311 msgid "The current page in the document" msgstr "" -#: gtk/gtkprintoperation.c:1035 +#: gtk/gtkprintoperation.c:1061 msgid "Use full page" msgstr "" -#: gtk/gtkprintoperation.c:1036 +#: gtk/gtkprintoperation.c:1062 msgid "" "TRUE if the origin of the context should be at the corner of the page and " "not the corner of the imageable area" msgstr "" -#: gtk/gtkprintoperation.c:1057 +#: gtk/gtkprintoperation.c:1083 msgid "" "TRUE if the print operation will continue to report on the print job status " "after the print data has been sent to the printer or print server." msgstr "" -#: gtk/gtkprintoperation.c:1074 +#: gtk/gtkprintoperation.c:1100 msgid "Unit" msgstr "" -#: gtk/gtkprintoperation.c:1075 +#: gtk/gtkprintoperation.c:1101 msgid "The unit in which distances can be measured in the context" msgstr "" -#: gtk/gtkprintoperation.c:1092 +#: gtk/gtkprintoperation.c:1118 msgid "Show Dialog" msgstr "" -#: gtk/gtkprintoperation.c:1093 +#: gtk/gtkprintoperation.c:1119 msgid "TRUE if a progress dialog is shown while printing." msgstr "" -#: gtk/gtkprintoperation.c:1116 +#: gtk/gtkprintoperation.c:1142 msgid "Allow Async" msgstr "" -#: gtk/gtkprintoperation.c:1117 +#: gtk/gtkprintoperation.c:1143 msgid "TRUE if print process may run asynchronous." msgstr "" -#: gtk/gtkprintoperation.c:1139 gtk/gtkprintoperation.c:1140 +#: gtk/gtkprintoperation.c:1165 gtk/gtkprintoperation.c:1166 msgid "Export filename" msgstr "" -#: gtk/gtkprintoperation.c:1154 +#: gtk/gtkprintoperation.c:1180 msgid "Status" msgstr "" -#: gtk/gtkprintoperation.c:1155 +#: gtk/gtkprintoperation.c:1181 msgid "The status of the print operation" msgstr "" -#: gtk/gtkprintoperation.c:1175 +#: gtk/gtkprintoperation.c:1201 msgid "Status String" msgstr "" -#: gtk/gtkprintoperation.c:1176 +#: gtk/gtkprintoperation.c:1202 msgid "A human-readable description of the status" msgstr "" -#: gtk/gtkprintoperation.c:1194 +#: gtk/gtkprintoperation.c:1220 msgid "Custom tab label" msgstr "" -#: gtk/gtkprintoperation.c:1195 +#: gtk/gtkprintoperation.c:1221 msgid "Label for the tab containing custom widgets." msgstr "" -#: gtk/gtkprintoperation.c:1210 gtk/gtkprintunixdialog.c:309 +#: gtk/gtkprintoperation.c:1236 gtk/gtkprintunixdialog.c:345 msgid "Support Selection" msgstr "" -#: gtk/gtkprintoperation.c:1211 +#: gtk/gtkprintoperation.c:1237 msgid "TRUE if the print operation will support print of selection." msgstr "" -#: gtk/gtkprintoperation.c:1227 gtk/gtkprintunixdialog.c:317 +#: gtk/gtkprintoperation.c:1253 gtk/gtkprintunixdialog.c:353 msgid "Has Selection" msgstr "" -#: gtk/gtkprintoperation.c:1228 +#: gtk/gtkprintoperation.c:1254 msgid "TRUE if a selecion exists." msgstr "" -#: gtk/gtkprintunixdialog.c:267 +#: gtk/gtkprintoperation.c:1269 gtk/gtkprintunixdialog.c:361 +msgid "Embed Page Setup" +msgstr "" + +#: gtk/gtkprintoperation.c:1270 +msgid "TRUE if page setup combos are embedded in GtkPrintDialog" +msgstr "" + +#: gtk/gtkprintoperation.c:1291 +msgid "Number of Pages To Print" +msgstr "" + +#: gtk/gtkprintoperation.c:1292 +msgid "The number of pages that will be printed." +msgstr "" + +#: gtk/gtkprintunixdialog.c:303 msgid "The GtkPageSetup to use" msgstr "" -#: gtk/gtkprintunixdialog.c:292 +#: gtk/gtkprintunixdialog.c:328 msgid "Selected Printer" msgstr "" -#: gtk/gtkprintunixdialog.c:293 +#: gtk/gtkprintunixdialog.c:329 msgid "The GtkPrinter which is selected" msgstr "" -#: gtk/gtkprintunixdialog.c:300 +#: gtk/gtkprintunixdialog.c:336 msgid "Manual Capabilites" msgstr "" -#: gtk/gtkprintunixdialog.c:301 +#: gtk/gtkprintunixdialog.c:337 msgid "Capabilities the application can handle" msgstr "" -#: gtk/gtkprintunixdialog.c:310 +#: gtk/gtkprintunixdialog.c:346 msgid "Whether the dialog supports selection" msgstr "" -#: gtk/gtkprintunixdialog.c:318 +#: gtk/gtkprintunixdialog.c:354 msgid "Whether the application has a selection" msgstr "" +#: gtk/gtkprintunixdialog.c:362 +msgid "TRUE if page setup combos are embedded in GtkPrintUnixDialog" +msgstr "" + #: gtk/gtkprogress.c:102 msgid "Activity mode" msgstr "" @@ -4655,11 +4768,11 @@ msgid "" "Display a second forward arrow button on the opposite end of the scrollbar" msgstr "" -#: gtk/gtkscrolledwindow.c:218 gtk/gtktext.c:545 gtk/gtktreeview.c:578 +#: gtk/gtkscrolledwindow.c:218 gtk/gtktext.c:545 gtk/gtktreeview.c:569 msgid "Horizontal Adjustment" msgstr "" -#: gtk/gtkscrolledwindow.c:225 gtk/gtktext.c:553 gtk/gtktreeview.c:586 +#: gtk/gtkscrolledwindow.c:225 gtk/gtktext.c:553 gtk/gtktreeview.c:577 msgid "Vertical Adjustment" msgstr "" @@ -5171,21 +5284,21 @@ msgstr "" msgid "Whether tooltips should be shown on widgets" msgstr "" -#: gtk/gtksizegroup.c:293 +#: gtk/gtksizegroup.c:301 msgid "Mode" msgstr "" -#: gtk/gtksizegroup.c:294 +#: gtk/gtksizegroup.c:302 msgid "" "The directions in which the size group affects the requested sizes of its " "component widgets" msgstr "" -#: gtk/gtksizegroup.c:310 +#: gtk/gtksizegroup.c:318 msgid "Ignore hidden" msgstr "" -#: gtk/gtksizegroup.c:311 +#: gtk/gtksizegroup.c:319 msgid "" "If TRUE, unmapped widgets are ignored when determining the size of the group" msgstr "" @@ -5253,58 +5366,62 @@ msgstr "" msgid "Style of bevel around the statusbar text" msgstr "" -#: gtk/gtkstatusicon.c:268 +#: gtk/gtkstatusicon.c:271 msgid "The size of the icon" msgstr "" -#: gtk/gtkstatusicon.c:278 +#: gtk/gtkstatusicon.c:281 msgid "The screen where this status icon will be displayed" msgstr "" -#: gtk/gtkstatusicon.c:285 +#: gtk/gtkstatusicon.c:288 msgid "Blinking" msgstr "" -#: gtk/gtkstatusicon.c:286 +#: gtk/gtkstatusicon.c:289 msgid "Whether or not the status icon is blinking" msgstr "" -#: gtk/gtkstatusicon.c:294 +#: gtk/gtkstatusicon.c:297 msgid "Whether or not the status icon is visible" msgstr "" -#: gtk/gtkstatusicon.c:310 +#: gtk/gtkstatusicon.c:313 msgid "Whether or not the status icon is embedded" msgstr "" -#: gtk/gtkstatusicon.c:326 gtk/gtktrayicon-x11.c:111 +#: gtk/gtkstatusicon.c:329 gtk/gtktrayicon-x11.c:111 msgid "The orientation of the tray" msgstr "" -#: gtk/gtkstatusicon.c:353 gtk/gtkwidget.c:632 +#: gtk/gtkstatusicon.c:356 gtk/gtkwidget.c:634 msgid "Has tooltip" msgstr "" -#: gtk/gtkstatusicon.c:354 +#: gtk/gtkstatusicon.c:357 msgid "Whether this tray icon has a tooltip" msgstr "" -#: gtk/gtkstatusicon.c:375 gtk/gtkwidget.c:653 +#: gtk/gtkstatusicon.c:382 gtk/gtkwidget.c:655 msgid "Tooltip Text" msgstr "" -#: gtk/gtkstatusicon.c:376 gtk/gtkwidget.c:654 gtk/gtkwidget.c:675 +#: gtk/gtkstatusicon.c:383 gtk/gtkwidget.c:656 gtk/gtkwidget.c:677 msgid "The contents of the tooltip for this widget" msgstr "" -#: gtk/gtkstatusicon.c:399 gtk/gtkwidget.c:674 +#: gtk/gtkstatusicon.c:406 gtk/gtkwidget.c:676 msgid "Tooltip markup" msgstr "" -#: gtk/gtkstatusicon.c:400 +#: gtk/gtkstatusicon.c:407 msgid "The contents of the tooltip for this tray icon" msgstr "" +#: gtk/gtkstatusicon.c:425 +msgid "The title of this tray icon" +msgstr "" + #: gtk/gtktable.c:129 msgid "Rows" msgstr "" @@ -5564,7 +5681,7 @@ msgid "" "such as PANGO_SCALE_X_LARGE" msgstr "" -#: gtk/gtktexttag.c:360 gtk/gtktextview.c:591 +#: gtk/gtktexttag.c:360 gtk/gtktextview.c:592 msgid "Left, right, or center justification" msgstr "" @@ -5578,7 +5695,7 @@ msgstr "" msgid "Left margin" msgstr "" -#: gtk/gtktexttag.c:387 gtk/gtktextview.c:600 +#: gtk/gtktexttag.c:387 gtk/gtktextview.c:601 msgid "Width of the left margin in pixels" msgstr "" @@ -5586,15 +5703,15 @@ msgstr "" msgid "Right margin" msgstr "" -#: gtk/gtktexttag.c:397 gtk/gtktextview.c:610 +#: gtk/gtktexttag.c:397 gtk/gtktextview.c:611 msgid "Width of the right margin in pixels" msgstr "" -#: gtk/gtktexttag.c:407 gtk/gtktextview.c:619 +#: gtk/gtktexttag.c:407 gtk/gtktextview.c:620 msgid "Indent" msgstr "" -#: gtk/gtktexttag.c:408 gtk/gtktextview.c:620 +#: gtk/gtktexttag.c:408 gtk/gtktextview.c:621 msgid "Amount to indent the paragraph, in pixels" msgstr "" @@ -5608,7 +5725,7 @@ msgstr "" msgid "Pixels above lines" msgstr "" -#: gtk/gtktexttag.c:429 gtk/gtktextview.c:544 +#: gtk/gtktexttag.c:429 gtk/gtktextview.c:545 msgid "Pixels of blank space above paragraphs" msgstr "" @@ -5616,7 +5733,7 @@ msgstr "" msgid "Pixels below lines" msgstr "" -#: gtk/gtktexttag.c:439 gtk/gtktextview.c:554 +#: gtk/gtktexttag.c:439 gtk/gtktextview.c:555 msgid "Pixels of blank space below paragraphs" msgstr "" @@ -5624,20 +5741,20 @@ msgstr "" msgid "Pixels inside wrap" msgstr "" -#: gtk/gtktexttag.c:449 gtk/gtktextview.c:564 +#: gtk/gtktexttag.c:449 gtk/gtktextview.c:565 msgid "Pixels of blank space between wrapped lines in a paragraph" msgstr "" -#: gtk/gtktexttag.c:476 gtk/gtktextview.c:582 +#: gtk/gtktexttag.c:476 gtk/gtktextview.c:583 msgid "" "Whether to wrap lines never, at word boundaries, or at character boundaries" msgstr "" -#: gtk/gtktexttag.c:485 gtk/gtktextview.c:629 +#: gtk/gtktexttag.c:485 gtk/gtktextview.c:630 msgid "Tabs" msgstr "" -#: gtk/gtktexttag.c:486 gtk/gtktextview.c:630 +#: gtk/gtktexttag.c:486 gtk/gtktextview.c:631 msgid "Custom tabs for this text" msgstr "" @@ -5781,63 +5898,63 @@ msgstr "" msgid "Whether this tag affects the paragraph background color" msgstr "" -#: gtk/gtktextview.c:543 +#: gtk/gtktextview.c:544 msgid "Pixels Above Lines" msgstr "" -#: gtk/gtktextview.c:553 +#: gtk/gtktextview.c:554 msgid "Pixels Below Lines" msgstr "" -#: gtk/gtktextview.c:563 +#: gtk/gtktextview.c:564 msgid "Pixels Inside Wrap" msgstr "" -#: gtk/gtktextview.c:581 +#: gtk/gtktextview.c:582 msgid "Wrap Mode" msgstr "" -#: gtk/gtktextview.c:599 +#: gtk/gtktextview.c:600 msgid "Left Margin" msgstr "" -#: gtk/gtktextview.c:609 +#: gtk/gtktextview.c:610 msgid "Right Margin" msgstr "" -#: gtk/gtktextview.c:637 +#: gtk/gtktextview.c:638 msgid "Cursor Visible" msgstr "" -#: gtk/gtktextview.c:638 +#: gtk/gtktextview.c:639 msgid "If the insertion cursor is shown" msgstr "" -#: gtk/gtktextview.c:645 +#: gtk/gtktextview.c:646 msgid "Buffer" msgstr "" -#: gtk/gtktextview.c:646 +#: gtk/gtktextview.c:647 msgid "The buffer which is displayed" msgstr "" -#: gtk/gtktextview.c:654 +#: gtk/gtktextview.c:655 msgid "Whether entered text overwrites existing contents" msgstr "" -#: gtk/gtktextview.c:661 +#: gtk/gtktextview.c:662 msgid "Accepts tab" msgstr "" -#: gtk/gtktextview.c:662 +#: gtk/gtktextview.c:663 msgid "Whether Tab will result in a tab character being entered" msgstr "" -#: gtk/gtktextview.c:691 +#: gtk/gtktextview.c:692 msgid "Error underline color" msgstr "" -#: gtk/gtktextview.c:692 +#: gtk/gtktextview.c:693 msgid "Color with which to draw error-indication underlines" msgstr "" @@ -6016,342 +6133,350 @@ msgstr "" msgid "Spacing in pixels between the icon and label" msgstr "" -#: gtk/gtktoolitem.c:191 +#: gtk/gtktoolitem.c:207 msgid "" "Whether the toolbar item is considered important. When TRUE, toolbar buttons " "show text in GTK_TOOLBAR_BOTH_HORIZ mode" msgstr "" -#: gtk/gtktreemodelsort.c:274 +#: gtk/gtktreemodelsort.c:278 msgid "TreeModelSort Model" msgstr "" -#: gtk/gtktreemodelsort.c:275 +#: gtk/gtktreemodelsort.c:279 msgid "The model for the TreeModelSort to sort" msgstr "" -#: gtk/gtktreeview.c:570 +#: gtk/gtktreeview.c:561 msgid "TreeView Model" msgstr "" -#: gtk/gtktreeview.c:571 +#: gtk/gtktreeview.c:562 msgid "The model for the tree view" msgstr "" -#: gtk/gtktreeview.c:579 +#: gtk/gtktreeview.c:570 msgid "Horizontal Adjustment for the widget" msgstr "" -#: gtk/gtktreeview.c:587 +#: gtk/gtktreeview.c:578 msgid "Vertical Adjustment for the widget" msgstr "" -#: gtk/gtktreeview.c:594 +#: gtk/gtktreeview.c:585 msgid "Headers Visible" msgstr "" -#: gtk/gtktreeview.c:595 +#: gtk/gtktreeview.c:586 msgid "Show the column header buttons" msgstr "" -#: gtk/gtktreeview.c:602 +#: gtk/gtktreeview.c:593 msgid "Headers Clickable" msgstr "" -#: gtk/gtktreeview.c:603 +#: gtk/gtktreeview.c:594 msgid "Column headers respond to click events" msgstr "" -#: gtk/gtktreeview.c:610 +#: gtk/gtktreeview.c:601 msgid "Expander Column" msgstr "" -#: gtk/gtktreeview.c:611 +#: gtk/gtktreeview.c:602 msgid "Set the column for the expander column" msgstr "" -#: gtk/gtktreeview.c:626 +#: gtk/gtktreeview.c:617 msgid "Rules Hint" msgstr "" -#: gtk/gtktreeview.c:627 +#: gtk/gtktreeview.c:618 msgid "Set a hint to the theme engine to draw rows in alternating colors" msgstr "" -#: gtk/gtktreeview.c:634 +#: gtk/gtktreeview.c:625 msgid "Enable Search" msgstr "" -#: gtk/gtktreeview.c:635 +#: gtk/gtktreeview.c:626 msgid "View allows user to search through columns interactively" msgstr "" -#: gtk/gtktreeview.c:642 +#: gtk/gtktreeview.c:633 msgid "Search Column" msgstr "" -#: gtk/gtktreeview.c:643 +#: gtk/gtktreeview.c:634 msgid "Model column to search through during interactive search" msgstr "" -#: gtk/gtktreeview.c:663 +#: gtk/gtktreeview.c:654 msgid "Fixed Height Mode" msgstr "" -#: gtk/gtktreeview.c:664 +#: gtk/gtktreeview.c:655 msgid "Speeds up GtkTreeView by assuming that all rows have the same height" msgstr "" -#: gtk/gtktreeview.c:684 +#: gtk/gtktreeview.c:675 msgid "Hover Selection" msgstr "" -#: gtk/gtktreeview.c:685 +#: gtk/gtktreeview.c:676 msgid "Whether the selection should follow the pointer" msgstr "" -#: gtk/gtktreeview.c:704 +#: gtk/gtktreeview.c:695 msgid "Hover Expand" msgstr "" -#: gtk/gtktreeview.c:705 +#: gtk/gtktreeview.c:696 msgid "" "Whether rows should be expanded/collapsed when the pointer moves over them" msgstr "" -#: gtk/gtktreeview.c:719 +#: gtk/gtktreeview.c:710 msgid "Show Expanders" msgstr "" -#: gtk/gtktreeview.c:720 +#: gtk/gtktreeview.c:711 msgid "View has expanders" msgstr "" -#: gtk/gtktreeview.c:734 +#: gtk/gtktreeview.c:725 msgid "Level Indentation" msgstr "" -#: gtk/gtktreeview.c:735 +#: gtk/gtktreeview.c:726 msgid "Extra indentation for each level" msgstr "" -#: gtk/gtktreeview.c:744 +#: gtk/gtktreeview.c:735 msgid "Rubber Banding" msgstr "" -#: gtk/gtktreeview.c:745 +#: gtk/gtktreeview.c:736 msgid "" "Whether to enable selection of multiple items by dragging the mouse pointer" msgstr "" -#: gtk/gtktreeview.c:752 +#: gtk/gtktreeview.c:743 msgid "Enable Grid Lines" msgstr "" -#: gtk/gtktreeview.c:753 +#: gtk/gtktreeview.c:744 msgid "Whether grid lines should be drawn in the tree view" msgstr "" -#: gtk/gtktreeview.c:761 +#: gtk/gtktreeview.c:752 msgid "Enable Tree Lines" msgstr "" -#: gtk/gtktreeview.c:762 +#: gtk/gtktreeview.c:753 msgid "Whether tree lines should be drawn in the tree view" msgstr "" -#: gtk/gtktreeview.c:770 +#: gtk/gtktreeview.c:761 msgid "The column in the model containing the tooltip texts for the rows" msgstr "" -#: gtk/gtktreeview.c:792 +#: gtk/gtktreeview.c:783 msgid "Vertical Separator Width" msgstr "" -#: gtk/gtktreeview.c:793 +#: gtk/gtktreeview.c:784 msgid "Vertical space between cells. Must be an even number" msgstr "" -#: gtk/gtktreeview.c:801 +#: gtk/gtktreeview.c:792 msgid "Horizontal Separator Width" msgstr "" -#: gtk/gtktreeview.c:802 +#: gtk/gtktreeview.c:793 msgid "Horizontal space between cells. Must be an even number" msgstr "" -#: gtk/gtktreeview.c:810 +#: gtk/gtktreeview.c:801 msgid "Allow Rules" msgstr "" -#: gtk/gtktreeview.c:811 +#: gtk/gtktreeview.c:802 msgid "Allow drawing of alternating color rows" msgstr "" -#: gtk/gtktreeview.c:817 +#: gtk/gtktreeview.c:808 msgid "Indent Expanders" msgstr "" -#: gtk/gtktreeview.c:818 +#: gtk/gtktreeview.c:809 msgid "Make the expanders indented" msgstr "" -#: gtk/gtktreeview.c:824 +#: gtk/gtktreeview.c:815 msgid "Even Row Color" msgstr "" -#: gtk/gtktreeview.c:825 +#: gtk/gtktreeview.c:816 msgid "Color to use for even rows" msgstr "" -#: gtk/gtktreeview.c:831 +#: gtk/gtktreeview.c:822 msgid "Odd Row Color" msgstr "" -#: gtk/gtktreeview.c:832 +#: gtk/gtktreeview.c:823 msgid "Color to use for odd rows" msgstr "" -#: gtk/gtktreeview.c:838 +#: gtk/gtktreeview.c:829 msgid "Row Ending details" msgstr "" -#: gtk/gtktreeview.c:839 +#: gtk/gtktreeview.c:830 msgid "Enable extended row background theming" msgstr "" -#: gtk/gtktreeview.c:845 +#: gtk/gtktreeview.c:836 msgid "Grid line width" msgstr "" -#: gtk/gtktreeview.c:846 +#: gtk/gtktreeview.c:837 msgid "Width, in pixels, of the tree view grid lines" msgstr "" -#: gtk/gtktreeview.c:852 +#: gtk/gtktreeview.c:843 msgid "Tree line width" msgstr "" -#: gtk/gtktreeview.c:853 +#: gtk/gtktreeview.c:844 msgid "Width, in pixels, of the tree view lines" msgstr "" -#: gtk/gtktreeview.c:859 +#: gtk/gtktreeview.c:850 msgid "Grid line pattern" msgstr "" -#: gtk/gtktreeview.c:860 +#: gtk/gtktreeview.c:851 msgid "Dash pattern used to draw the tree view grid lines" msgstr "" -#: gtk/gtktreeview.c:866 +#: gtk/gtktreeview.c:857 msgid "Tree line pattern" msgstr "" -#: gtk/gtktreeview.c:867 +#: gtk/gtktreeview.c:858 msgid "Dash pattern used to draw the tree view lines" msgstr "" -#: gtk/gtktreeviewcolumn.c:192 +#: gtk/gtktreeviewcolumn.c:193 msgid "Whether to display the column" msgstr "" -#: gtk/gtktreeviewcolumn.c:199 gtk/gtkwindow.c:537 +#: gtk/gtktreeviewcolumn.c:200 gtk/gtkwindow.c:537 msgid "Resizable" msgstr "" -#: gtk/gtktreeviewcolumn.c:200 +#: gtk/gtktreeviewcolumn.c:201 msgid "Column is user-resizable" msgstr "" -#: gtk/gtktreeviewcolumn.c:208 +#: gtk/gtktreeviewcolumn.c:209 msgid "Current width of the column" msgstr "" -#: gtk/gtktreeviewcolumn.c:217 +#: gtk/gtktreeviewcolumn.c:218 msgid "Space which is inserted between cells" msgstr "" -#: gtk/gtktreeviewcolumn.c:225 +#: gtk/gtktreeviewcolumn.c:226 msgid "Sizing" msgstr "" -#: gtk/gtktreeviewcolumn.c:226 +#: gtk/gtktreeviewcolumn.c:227 msgid "Resize mode of the column" msgstr "" -#: gtk/gtktreeviewcolumn.c:234 +#: gtk/gtktreeviewcolumn.c:235 msgid "Fixed Width" msgstr "" -#: gtk/gtktreeviewcolumn.c:235 +#: gtk/gtktreeviewcolumn.c:236 msgid "Current fixed width of the column" msgstr "" -#: gtk/gtktreeviewcolumn.c:244 +#: gtk/gtktreeviewcolumn.c:245 msgid "Minimum Width" msgstr "" -#: gtk/gtktreeviewcolumn.c:245 +#: gtk/gtktreeviewcolumn.c:246 msgid "Minimum allowed width of the column" msgstr "" -#: gtk/gtktreeviewcolumn.c:254 +#: gtk/gtktreeviewcolumn.c:255 msgid "Maximum Width" msgstr "" -#: gtk/gtktreeviewcolumn.c:255 +#: gtk/gtktreeviewcolumn.c:256 msgid "Maximum allowed width of the column" msgstr "" -#: gtk/gtktreeviewcolumn.c:265 +#: gtk/gtktreeviewcolumn.c:266 msgid "Title to appear in column header" msgstr "" -#: gtk/gtktreeviewcolumn.c:273 +#: gtk/gtktreeviewcolumn.c:274 msgid "Column gets share of extra width allocated to the widget" msgstr "" -#: gtk/gtktreeviewcolumn.c:280 +#: gtk/gtktreeviewcolumn.c:281 msgid "Clickable" msgstr "" -#: gtk/gtktreeviewcolumn.c:281 +#: gtk/gtktreeviewcolumn.c:282 msgid "Whether the header can be clicked" msgstr "" -#: gtk/gtktreeviewcolumn.c:289 +#: gtk/gtktreeviewcolumn.c:290 msgid "Widget" msgstr "" -#: gtk/gtktreeviewcolumn.c:290 +#: gtk/gtktreeviewcolumn.c:291 msgid "Widget to put in column header button instead of column title" msgstr "" -#: gtk/gtktreeviewcolumn.c:298 +#: gtk/gtktreeviewcolumn.c:299 msgid "X Alignment of the column header text or widget" msgstr "" -#: gtk/gtktreeviewcolumn.c:308 +#: gtk/gtktreeviewcolumn.c:309 msgid "Whether the column can be reordered around the headers" msgstr "" -#: gtk/gtktreeviewcolumn.c:315 +#: gtk/gtktreeviewcolumn.c:316 msgid "Sort indicator" msgstr "" -#: gtk/gtktreeviewcolumn.c:316 +#: gtk/gtktreeviewcolumn.c:317 msgid "Whether to show a sort indicator" msgstr "" -#: gtk/gtktreeviewcolumn.c:323 +#: gtk/gtktreeviewcolumn.c:324 msgid "Sort order" msgstr "" -#: gtk/gtktreeviewcolumn.c:324 +#: gtk/gtktreeviewcolumn.c:325 msgid "Sort direction the sort indicator should indicate" msgstr "" +#: gtk/gtktreeviewcolumn.c:341 +msgid "Sort column ID" +msgstr "" + +#: gtk/gtktreeviewcolumn.c:342 +msgid "Logical sort column ID this column sorts on when selected for sorting" +msgstr "" + #: gtk/gtkuimanager.c:223 msgid "Whether tearoff menu items should be added to menus" msgstr "" @@ -6380,281 +6505,289 @@ msgstr "" msgid "Determines how the shadowed box around the viewport is drawn" msgstr "" -#: gtk/gtkwidget.c:483 +#: gtk/gtkwidget.c:485 msgid "Widget name" msgstr "" -#: gtk/gtkwidget.c:484 +#: gtk/gtkwidget.c:486 msgid "The name of the widget" msgstr "" -#: gtk/gtkwidget.c:490 +#: gtk/gtkwidget.c:492 msgid "Parent widget" msgstr "" -#: gtk/gtkwidget.c:491 +#: gtk/gtkwidget.c:493 msgid "The parent widget of this widget. Must be a Container widget" msgstr "" -#: gtk/gtkwidget.c:498 +#: gtk/gtkwidget.c:500 msgid "Width request" msgstr "" -#: gtk/gtkwidget.c:499 +#: gtk/gtkwidget.c:501 msgid "" "Override for width request of the widget, or -1 if natural request should be " "used" msgstr "" -#: gtk/gtkwidget.c:507 +#: gtk/gtkwidget.c:509 msgid "Height request" msgstr "" -#: gtk/gtkwidget.c:508 +#: gtk/gtkwidget.c:510 msgid "" "Override for height request of the widget, or -1 if natural request should " "be used" msgstr "" -#: gtk/gtkwidget.c:517 +#: gtk/gtkwidget.c:519 msgid "Whether the widget is visible" msgstr "" -#: gtk/gtkwidget.c:524 +#: gtk/gtkwidget.c:526 msgid "Whether the widget responds to input" msgstr "" -#: gtk/gtkwidget.c:530 +#: gtk/gtkwidget.c:532 msgid "Application paintable" msgstr "" -#: gtk/gtkwidget.c:531 +#: gtk/gtkwidget.c:533 msgid "Whether the application will paint directly on the widget" msgstr "" -#: gtk/gtkwidget.c:537 +#: gtk/gtkwidget.c:539 msgid "Can focus" msgstr "" -#: gtk/gtkwidget.c:538 +#: gtk/gtkwidget.c:540 msgid "Whether the widget can accept the input focus" msgstr "" -#: gtk/gtkwidget.c:544 +#: gtk/gtkwidget.c:546 msgid "Has focus" msgstr "" -#: gtk/gtkwidget.c:545 +#: gtk/gtkwidget.c:547 msgid "Whether the widget has the input focus" msgstr "" -#: gtk/gtkwidget.c:551 +#: gtk/gtkwidget.c:553 msgid "Is focus" msgstr "" -#: gtk/gtkwidget.c:552 +#: gtk/gtkwidget.c:554 msgid "Whether the widget is the focus widget within the toplevel" msgstr "" -#: gtk/gtkwidget.c:558 +#: gtk/gtkwidget.c:560 msgid "Can default" msgstr "" -#: gtk/gtkwidget.c:559 +#: gtk/gtkwidget.c:561 msgid "Whether the widget can be the default widget" msgstr "" -#: gtk/gtkwidget.c:565 +#: gtk/gtkwidget.c:567 msgid "Has default" msgstr "" -#: gtk/gtkwidget.c:566 +#: gtk/gtkwidget.c:568 msgid "Whether the widget is the default widget" msgstr "" -#: gtk/gtkwidget.c:572 +#: gtk/gtkwidget.c:574 msgid "Receives default" msgstr "" -#: gtk/gtkwidget.c:573 +#: gtk/gtkwidget.c:575 msgid "If TRUE, the widget will receive the default action when it is focused" msgstr "" -#: gtk/gtkwidget.c:579 +#: gtk/gtkwidget.c:581 msgid "Composite child" msgstr "" -#: gtk/gtkwidget.c:580 +#: gtk/gtkwidget.c:582 msgid "Whether the widget is part of a composite widget" msgstr "" -#: gtk/gtkwidget.c:586 +#: gtk/gtkwidget.c:588 msgid "Style" msgstr "" -#: gtk/gtkwidget.c:587 +#: gtk/gtkwidget.c:589 msgid "" "The style of the widget, which contains information about how it will look " "(colors etc)" msgstr "" -#: gtk/gtkwidget.c:593 +#: gtk/gtkwidget.c:595 msgid "Events" msgstr "" -#: gtk/gtkwidget.c:594 +#: gtk/gtkwidget.c:596 msgid "The event mask that decides what kind of GdkEvents this widget gets" msgstr "" -#: gtk/gtkwidget.c:601 +#: gtk/gtkwidget.c:603 msgid "Extension events" msgstr "" -#: gtk/gtkwidget.c:602 +#: gtk/gtkwidget.c:604 msgid "The mask that decides what kind of extension events this widget gets" msgstr "" -#: gtk/gtkwidget.c:609 +#: gtk/gtkwidget.c:611 msgid "No show all" msgstr "" -#: gtk/gtkwidget.c:610 +#: gtk/gtkwidget.c:612 msgid "Whether gtk_widget_show_all() should not affect this widget" msgstr "" -#: gtk/gtkwidget.c:633 +#: gtk/gtkwidget.c:635 msgid "Whether this widget has a tooltip" msgstr "" -#: gtk/gtkwidget.c:689 +#: gtk/gtkwidget.c:691 msgid "Window" msgstr "" -#: gtk/gtkwidget.c:690 +#: gtk/gtkwidget.c:692 msgid "The widget's window if it is realized" msgstr "" -#: gtk/gtkwidget.c:2212 +#: gtk/gtkwidget.c:706 +msgid "Double Buffered" +msgstr "" + +#: gtk/gtkwidget.c:707 +msgid "Whether or not the widget is double buffered" +msgstr "" + +#: gtk/gtkwidget.c:2229 msgid "Interior Focus" msgstr "" -#: gtk/gtkwidget.c:2213 +#: gtk/gtkwidget.c:2230 msgid "Whether to draw the focus indicator inside widgets" msgstr "" -#: gtk/gtkwidget.c:2219 +#: gtk/gtkwidget.c:2236 msgid "Focus linewidth" msgstr "" -#: gtk/gtkwidget.c:2220 +#: gtk/gtkwidget.c:2237 msgid "Width, in pixels, of the focus indicator line" msgstr "" -#: gtk/gtkwidget.c:2226 +#: gtk/gtkwidget.c:2243 msgid "Focus line dash pattern" msgstr "" -#: gtk/gtkwidget.c:2227 +#: gtk/gtkwidget.c:2244 msgid "Dash pattern used to draw the focus indicator" msgstr "" -#: gtk/gtkwidget.c:2232 +#: gtk/gtkwidget.c:2249 msgid "Focus padding" msgstr "" -#: gtk/gtkwidget.c:2233 +#: gtk/gtkwidget.c:2250 msgid "Width, in pixels, between focus indicator and the widget 'box'" msgstr "" -#: gtk/gtkwidget.c:2238 +#: gtk/gtkwidget.c:2255 msgid "Cursor color" msgstr "" -#: gtk/gtkwidget.c:2239 +#: gtk/gtkwidget.c:2256 msgid "Color with which to draw insertion cursor" msgstr "" -#: gtk/gtkwidget.c:2244 +#: gtk/gtkwidget.c:2261 msgid "Secondary cursor color" msgstr "" -#: gtk/gtkwidget.c:2245 +#: gtk/gtkwidget.c:2262 msgid "" "Color with which to draw the secondary insertion cursor when editing mixed " "right-to-left and left-to-right text" msgstr "" -#: gtk/gtkwidget.c:2250 +#: gtk/gtkwidget.c:2267 msgid "Cursor line aspect ratio" msgstr "" -#: gtk/gtkwidget.c:2251 +#: gtk/gtkwidget.c:2268 msgid "Aspect ratio with which to draw insertion cursor" msgstr "" -#: gtk/gtkwidget.c:2265 +#: gtk/gtkwidget.c:2282 msgid "Draw Border" msgstr "" -#: gtk/gtkwidget.c:2266 +#: gtk/gtkwidget.c:2283 msgid "Size of areas outside the widget's allocation to draw" msgstr "" -#: gtk/gtkwidget.c:2279 +#: gtk/gtkwidget.c:2296 msgid "Unvisited Link Color" msgstr "" -#: gtk/gtkwidget.c:2280 +#: gtk/gtkwidget.c:2297 msgid "Color of unvisited links" msgstr "" -#: gtk/gtkwidget.c:2293 +#: gtk/gtkwidget.c:2310 msgid "Visited Link Color" msgstr "" -#: gtk/gtkwidget.c:2294 +#: gtk/gtkwidget.c:2311 msgid "Color of visited links" msgstr "" -#: gtk/gtkwidget.c:2308 +#: gtk/gtkwidget.c:2325 msgid "Wide Separators" msgstr "" -#: gtk/gtkwidget.c:2309 +#: gtk/gtkwidget.c:2326 msgid "" "Whether separators have configurable width and should be drawn using a box " "instead of a line" msgstr "" -#: gtk/gtkwidget.c:2323 +#: gtk/gtkwidget.c:2340 msgid "Separator Width" msgstr "" -#: gtk/gtkwidget.c:2324 +#: gtk/gtkwidget.c:2341 msgid "The width of separators if wide-separators is TRUE" msgstr "" -#: gtk/gtkwidget.c:2338 +#: gtk/gtkwidget.c:2355 msgid "Separator Height" msgstr "" -#: gtk/gtkwidget.c:2339 +#: gtk/gtkwidget.c:2356 msgid "The height of separators if \"wide-separators\" is TRUE" msgstr "" -#: gtk/gtkwidget.c:2353 +#: gtk/gtkwidget.c:2370 msgid "Horizontal Scroll Arrow Length" msgstr "" -#: gtk/gtkwidget.c:2354 +#: gtk/gtkwidget.c:2371 msgid "The length of horizontal scroll arrows" msgstr "" -#: gtk/gtkwidget.c:2368 +#: gtk/gtkwidget.c:2385 msgid "Vertical Scroll Arrow Length" msgstr "" -#: gtk/gtkwidget.c:2369 +#: gtk/gtkwidget.c:2386 msgid "The length of vertical scroll arrows" msgstr "" diff --git a/po-properties/az.po b/po-properties/az.po index b89f631c15..dc76447453 100644 --- a/po-properties/az.po +++ b/po-properties/az.po @@ -32,7 +32,7 @@ msgid "" msgstr "" "Project-Id-Version: gtk+-properties.HEAD\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-06-15 20:53-0400\n" +"POT-Creation-Date: 2009-09-30 17:31-0400\n" "PO-Revision-Date: 2004-03-07 18:05+0200\n" "Last-Translator: Mətin Əmirov \n" "Language-Team: Azerbaijani Turkish