[gtk+/xi2: 981/981] Merge branch 'master' into xi2
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/xi2: 981/981] Merge branch 'master' into xi2
- Date: Tue, 4 May 2010 09:27:09 +0000 (UTC)
commit 90e0b05a4e5dea237f73276d2008aed2f95001dd
Merge: affc7e6 5098f34
Author: Carlos Garnacho <carlosg gnome org>
Date: Tue May 4 11:25:33 2010 +0200
Merge branch 'master' into xi2
Conflicts:
gdk/gdk.symbols
gdk/x11/gdkprivate-x11.h
gtk/gtkmain.c
gtk/gtkmenu.c
gtk/gtkprivate.h
gtk/gtktextview.c
gtk/gtktreeview.c
gtk/gtkwidget.c
gtk/gtkwindow.c
INSTALL.in | 4 +-
Makefile.am | 2 +-
NEWS | 128 +
README.in | 15 +-
build/Makefile.am | 4 +
build/win32/Makefile.am | 4 +
build/win32/vs9/Makefile.am | 16 +
build/win32/vs9/README.txt | 22 +
build/win32/vs9/gdk-pixbuf-csource.vcproj | 166 +
build/win32/vs9/gdk-pixbuf-query-loaders.vcproj | 166 +
build/win32/vs9/gdk-pixbuf.vcproj | 258 +
build/win32/vs9/gdk-win32.vcproj | 153 +
build/win32/vs9/gdk.vcprojin | 220 +
build/win32/vs9/gtk+.sln | 122 +
build/win32/vs9/gtk+.vsprops | 390 +
build/win32/vs9/gtk-demo.vcproj | 209 +
build/win32/vs9/gtk.vcprojin | 235 +
build/win32/vs9/install.vcproj | 78 +
config.h.win32.in | 24 +-
configure.in | 17 +-
demos/gtk-demo/appwindow.c | 2 +-
demos/gtk-demo/assistant.c | 2 +-
demos/gtk-demo/builder.c | 2 +-
demos/gtk-demo/button_box.c | 2 +-
demos/gtk-demo/clipboard.c | 2 +-
demos/gtk-demo/colorsel.c | 2 +-
demos/gtk-demo/combobox.c | 2 +-
demos/gtk-demo/dialog.c | 2 +-
demos/gtk-demo/drawingarea.c | 4 +-
demos/gtk-demo/editable_cells.c | 2 +-
demos/gtk-demo/entry_buffer.c | 2 +-
demos/gtk-demo/entry_completion.c | 2 +-
demos/gtk-demo/expander.c | 2 +-
demos/gtk-demo/hypertext.c | 2 +-
demos/gtk-demo/iconview.c | 2 +-
demos/gtk-demo/iconview_edit.c | 2 +-
demos/gtk-demo/images.c | 23 +-
demos/gtk-demo/infobar.c | 2 +-
demos/gtk-demo/links.c | 2 +-
demos/gtk-demo/list_store.c | 32 +-
demos/gtk-demo/menus.c | 4 +-
demos/gtk-demo/offscreen_window.c | 26 +-
demos/gtk-demo/offscreen_window2.c | 26 +-
demos/gtk-demo/panes.c | 2 +-
demos/gtk-demo/pickers.c | 2 +-
demos/gtk-demo/pixbufs.c | 2 +-
demos/gtk-demo/rotated_text.c | 2 +-
demos/gtk-demo/search_entry.c | 224 +-
demos/gtk-demo/sizegroup.c | 2 +-
demos/gtk-demo/spinner.c | 2 +-
demos/gtk-demo/stock_browser.c | 2 +-
demos/gtk-demo/textscroll.c | 2 +-
demos/gtk-demo/textview.c | 2 +-
demos/gtk-demo/toolpalette.c | 2 +-
demos/gtk-demo/tree_store.c | 2 +-
demos/gtk-demo/ui_manager.c | 2 +-
docs/RELEASE-HOWTO | 5 +-
docs/reference/gdk/gdk-docs.sgml | 4 +
docs/reference/gdk/tmpl/windows.sgml | 1 -
docs/reference/gtk/building.sgml | 20 +-
docs/reference/gtk/drawing-model.xml | 2 +-
docs/reference/gtk/gtk-docs.sgml | 9 +
docs/reference/gtk/gtk-sections.txt | 58 +-
docs/reference/gtk/gtk.types | 1 +
docs/reference/gtk/tmpl/.gitignore | 6 +
docs/reference/gtk/tmpl/gtkaction.sgml | 560 --
docs/reference/gtk/tmpl/gtkalignment.sgml | 141 -
docs/reference/gtk/tmpl/gtkarrow.sgml | 82 -
docs/reference/gtk/tmpl/gtkaspectframe.sgml | 88 -
docs/reference/gtk/tmpl/gtkassistant.sgml | 344 -
docs/reference/gtk/tmpl/gtkbbox.sgml | 210 -
docs/reference/gtk/tmpl/gtkbin.sgml | 54 -
docs/reference/gtk/tmpl/gtkbox.sgml | 291 -
docs/reference/gtk/tmpl/gtkbuildable.sgml | 193 -
docs/reference/gtk/tmpl/gtkbuilder.sgml | 456 --
docs/reference/gtk/tmpl/gtkcontainer.sgml | 295 +-
docs/reference/gtk/tmpl/gtkdnd.sgml | 15 +-
docs/reference/gtk/tmpl/gtkdrawingarea.sgml | 2 +-
docs/reference/gtk/tmpl/gtkhbox.sgml | 49 -
docs/reference/gtk/tmpl/gtklabel.sgml | 20 +-
docs/reference/gtk/tmpl/gtkmessagedialog.sgml | 213 -
docs/reference/gtk/tmpl/gtkplug.sgml | 126 -
docs/reference/gtk/tmpl/gtksocket.sgml | 170 -
docs/reference/gtk/tmpl/gtktesting.sgml | 177 -
docs/reference/gtk/tmpl/gtkvbbox.sgml | 98 -
docs/reference/gtk/tmpl/gtkvbox.sgml | 49 -
docs/reference/gtk/tmpl/gtkviewport.sgml | 134 -
docs/reference/gtk/tmpl/gtkvolumebutton.sgml | 35 -
docs/reference/gtk/tmpl/gtkvpaned.sgml | 35 -
docs/reference/gtk/tmpl/gtkvruler.sgml | 50 -
docs/reference/gtk/tmpl/gtkvscale.sgml | 51 -
docs/reference/gtk/tmpl/gtkvscrollbar.sgml | 40 -
docs/reference/gtk/tmpl/gtkvseparator.sgml | 41 -
docs/reference/libgail-util/tmpl/gailmisc.sgml | 125 -
docs/reference/libgail-util/tmpl/gailtextutil.sgml | 95 -
docs/tutorial/gtk-tut.sgml | 398 +-
examples/calendar/calendar.c | 4 +-
examples/entry/entry.c | 2 +-
examples/gtkdial/gtkdial.c | 4 +-
examples/progressbar/progressbar.c | 2 +-
examples/radiobuttons/radiobuttons.c | 2 +-
examples/rangewidgets/rangewidgets.c | 2 +-
examples/scribble-simple/scribble-simple.c | 2 +-
examples/scribble-xinput/Makefile | 5 +-
examples/scribble-xinput/scribble-xinput.c | 8 +-
examples/scrolledwin/scrolledwin.c | 2 +-
examples/text/text.c | 2 +-
gdk-pixbuf/Makefile.am | 1 +
gdk-pixbuf/gdk-pixbuf-io.c | 14 +-
gdk-pixbuf/gdk-pixbuf-loader.c | 6 +-
gdk-pixbuf/io-png.c | 4 +-
gdk-pixbuf/io-qtif.c | 2 +-
gdk-pixbuf/io-tga.c | 8 +-
gdk/Makefile.am | 16 +-
gdk/directfb/gdkcolor-directfb.c | 12 +-
gdk/directfb/gdkdisplay-directfb.c | 23 +-
gdk/directfb/gdkkeys-directfb.c | 15 +
gdk/directfb/gdkwindow-directfb.c | 15 +-
gdk/gdk.c | 6 +-
gdk/gdk.symbols | 6 +
gdk/gdkapplaunchcontext.c | 4 +-
gdk/gdkdisplay.c | 6 +-
gdk/gdkdraw.c | 12 +-
gdk/gdkevents.c | 2 +-
gdk/gdkpango.c | 14 +-
gdk/gdkpixbuf-drawable.c | 6 +-
gdk/gdkpixmap.c | 34 +-
gdk/gdkrectangle.c | 2 +-
gdk/gdkrgb.c | 8 +-
gdk/gdkscreen.c | 2 +-
gdk/gdkselection.c | 2 +-
gdk/gdkvisual.c | 4 +-
gdk/gdkwindow.c | 288 +-
gdk/gdkwindow.h | 13 +
gdk/x11/gdkapplaunchcontext-x11.c | 7 +
gdk/x11/gdkcolor-x11.c | 2 +-
gdk/x11/gdkdnd-x11.c | 16 +-
gdk/x11/gdkkeys-x11.c | 16 +-
gdk/x11/gdkprivate-x11.h | 2 -
gdk/x11/gdkscreen-x11.c | 61 +-
gdk/x11/gdkvisual-x11.c | 13 +-
gdk/x11/gdkwindow-x11.c | 34 +-
gtk/Makefile.am | 20 +-
gtk/compose-parse.py | 53 +-
gtk/gen-paper-names.c | 103 +-
gtk/gtk-compose-lookaside.txt | 18 -
gtk/gtk.h | 1 +
gtk/gtk.symbols | 19 +
gtk/gtkaboutdialog.c | 6 +-
gtk/gtkaccelgroup.c | 11 +-
gtk/gtkaccellabel.c | 4 +-
gtk/gtkaccessible.c | 20 +
gtk/gtkaccessible.h | 3 +-
gtk/gtkaction.c | 45 +-
gtk/gtkactivatable.c | 2 +-
gtk/gtkalignment.c | 218 +-
gtk/gtkarrow.c | 48 +-
gtk/gtkaspectframe.c | 48 +-
gtk/gtkassistant.c | 99 +-
gtk/gtkassistant.h | 30 +
gtk/gtkbbox.c | 103 +-
gtk/gtkbbox.h | 19 +
gtk/gtkbin.c | 140 +-
gtk/gtkbox.c | 1078 ++-
gtk/gtkbox.h | 22 +
gtk/gtkbuildable.c | 40 +-
gtk/gtkbuildable.h | 49 +
gtk/gtkbuilder.c | 271 +-
gtk/gtkbuilder.h | 31 +
gtk/gtkbutton.c | 192 +-
gtk/gtkcalendar.c | 64 +-
gtk/gtkcelleditable.c | 157 +-
gtk/gtkcellrenderer.c | 22 +-
gtk/gtkcellrendererpixbuf.c | 161 +-
gtk/gtkcellrendererspinner.c | 4 +-
gtk/gtkcellrenderertext.c | 8 +-
gtk/gtkcellrenderertoggle.c | 4 +-
gtk/gtkcellview.c | 10 +-
gtk/gtkcheckbutton.c | 35 +-
gtk/gtkcheckmenuitem.c | 14 +-
gtk/gtkclipboard.c | 4 +-
gtk/gtkclist.c | 106 +-
gtk/gtkcolorbutton.c | 4 +-
gtk/gtkcolorsel.c | 8 +-
gtk/gtkcombo.c | 16 +-
gtk/gtkcombobox.c | 55 +-
gtk/gtkcontainer.c | 36 +-
gtk/gtkctree.c | 30 +-
gtk/gtkcurve.c | 2 +-
gtk/gtkcustompaperunixdialog.c | 4 +-
gtk/gtkdebug.h | 25 +-
gtk/gtkdialog.c | 11 +-
gtk/gtkdnd-quartz.c | 10 +-
gtk/gtkdnd.c | 57 +-
gtk/gtkdrawingarea.c | 4 +-
gtk/gtkentry.c | 249 +-
gtk/gtkentrybuffer.c | 2 +-
gtk/gtkentrycompletion.c | 20 +-
gtk/gtkenums.h | 10 +
gtk/gtkeventbox.c | 20 +-
gtk/gtkexpander.c | 42 +-
gtk/gtkextendedlayout.c | 535 ++
gtk/gtkextendedlayout.h | 89 +
gtk/gtkfilechooser.c | 25 +-
gtk/gtkfilechooserbutton.c | 23 +-
gtk/gtkfilechooserdefault.c | 67 +-
gtk/gtkfilechooserdialog.c | 18 +-
gtk/gtkfilechooserentry.c | 2 +-
gtk/gtkfilefilter.c | 2 +-
gtk/gtkfilesel.c | 4 +-
gtk/gtkfilesystem.c | 24 +-
gtk/gtkfilesystem.h | 3 +-
gtk/gtkfilesystemmodel.c | 13 +-
gtk/gtkfixed.c | 21 +-
gtk/gtkfontbutton.c | 2 +-
gtk/gtkfontsel.c | 2 +-
gtk/gtkframe.c | 185 +-
gtk/gtkgamma.c | 2 +-
gtk/gtkhandlebox.c | 44 +-
gtk/gtkhbox.c | 25 +
gtk/gtkhscrollbar.c | 2 +-
gtk/gtkhsv.c | 20 +-
gtk/gtkiconfactory.c | 4 +-
gtk/gtkicontheme.c | 149 +-
gtk/gtkicontheme.h | 7 +
gtk/gtkiconview.c | 83 +-
gtk/gtkimage.c | 161 +-
gtk/gtkimagemenuitem.c | 11 +-
gtk/gtkimcontext.c | 2 +-
gtk/gtkimcontextsimpleseqs.h | 114 +-
gtk/gtkinfobar.c | 7 +-
gtk/gtkinputdialog.c | 4 +-
gtk/gtkinvisible.c | 8 +-
gtk/gtkitem.c | 4 +-
gtk/gtkitemfactory.c | 12 +-
gtk/gtklabel.c | 792 ++-
gtk/gtklayout.c | 31 +-
gtk/gtklinkbutton.c | 12 +-
gtk/gtklist.c | 38 +-
gtk/gtklistitem.c | 28 +-
gtk/gtkliststore.c | 8 +-
gtk/gtkmain.c | 39 +-
gtk/gtkmenu.c | 75 +-
gtk/gtkmenubar.c | 18 +-
gtk/gtkmenuitem.c | 59 +-
gtk/gtkmenushell.c | 78 +-
gtk/gtkmenutoolbutton.c | 10 +-
gtk/gtkmessagedialog.c | 53 +-
gtk/gtkmessagedialog.h | 37 +-
gtk/gtkmisc.c | 24 +-
gtk/gtkmnemonichash.c | 4 +-
gtk/gtkmountoperation.c | 4 +-
gtk/gtknotebook.c | 199 +-
gtk/gtkoffscreenwindow.c | 12 +-
gtk/gtkoldeditable.c | 12 +-
gtk/gtkoptionmenu.c | 38 +-
gtk/gtkorientable.c | 35 +-
gtk/gtkpagesetup.c | 14 +-
gtk/gtkpagesetupunixdialog.c | 4 +-
gtk/gtkpaned.c | 63 +-
gtk/gtkpapersize.c | 2 +-
gtk/gtkpathbar.c | 45 +-
gtk/gtkpixmap.c | 8 +-
gtk/gtkplug.c | 54 +-
gtk/gtkpreview.c | 4 +-
gtk/gtkprinteroptionset.c | 3 +-
gtk/gtkprinteroptionwidget.c | 2 +-
gtk/gtkprintjob.c | 2 +-
gtk/gtkprintoperation-unix.c | 4 +-
gtk/gtkprintoperation-win32.c | 2 +-
gtk/gtkprintoperation.c | 6 +-
gtk/gtkprintsettings.c | 20 +-
gtk/gtkprintunixdialog.c | 24 +-
gtk/gtkprivate.h | 57 +-
gtk/gtkprogress.c | 10 +-
gtk/gtkprogressbar.c | 10 +-
gtk/gtkradioaction.c | 4 +-
gtk/gtkradiobutton.c | 23 +-
gtk/gtkradiotoolbutton.c | 4 +-
gtk/gtkrange.c | 29 +-
gtk/gtkrbtree.c | 42 +-
gtk/gtkrc.c | 30 +-
gtk/gtkrc.h | 4 +
gtk/gtkrecentaction.c | 10 +-
gtk/gtkrecentchooser.c | 10 +-
gtk/gtkrecentchooserdefault.c | 4 +-
gtk/gtkrecentchooserdialog.c | 14 +-
gtk/gtkrecentchooserutils.c | 4 +-
gtk/gtkrecentmanager.c | 10 +-
gtk/gtkruler.c | 25 +-
gtk/gtkscale.c | 17 +-
gtk/gtkscalebutton.c | 2 +-
gtk/gtkscrollbar.c | 2 +-
gtk/gtkscrolledwindow.c | 330 +-
gtk/gtksearchenginetracker.c | 297 +-
gtk/gtkselection.c | 8 +-
gtk/gtkseparator.c | 12 +-
gtk/gtkshow.c | 2 +-
gtk/gtksizegroup.c | 218 +-
gtk/gtksizegroup.h | 11 +-
gtk/gtksocket-win32.c | 2 +-
gtk/gtksocket.c | 93 +-
gtk/gtkspinbutton.c | 30 +-
gtk/gtkspinner.c | 6 +-
gtk/gtkstatusbar.c | 16 +-
gtk/gtkstatusicon.c | 66 +-
gtk/gtkstyle.c | 86 +-
gtk/gtktable.c | 34 +-
gtk/gtktearoffmenuitem.c | 2 +-
gtk/gtktestutils.c | 9 +-
gtk/gtktext.c | 50 +-
gtk/gtktextbuffer.c | 8 +-
gtk/gtktextdisplay.c | 12 +-
gtk/gtktextiter.c | 6 +-
gtk/gtktextlayout.c | 4 +-
gtk/gtktextmark.c | 2 +-
gtk/gtktexttag.c | 2 +-
gtk/gtktexttagtable.c | 2 +-
gtk/gtktextutil.c | 8 +-
gtk/gtktextview.c | 157 +-
gtk/gtktextview.h | 3 +
gtk/gtktipsquery.c | 2 +-
gtk/gtktoggleaction.c | 4 +-
gtk/gtktogglebutton.c | 6 +-
gtk/gtktoolbar.c | 52 +-
gtk/gtktoolbutton.c | 6 +-
gtk/gtktoolitem.c | 17 +-
gtk/gtktoolitemgroup.c | 45 +-
gtk/gtktoolpalette.c | 9 +-
gtk/gtktooltip.c | 104 +-
gtk/gtktrayicon-x11.c | 190 +-
gtk/gtktrayicon.h | 2 +-
gtk/gtktree.c | 28 +-
gtk/gtktreeitem.c | 58 +-
gtk/gtktreemodel.c | 4 +-
gtk/gtktreemodelfilter.c | 8 +-
gtk/gtktreemodelsort.c | 2 +-
gtk/gtktreesortable.c | 8 +-
gtk/gtktreestore.c | 28 +-
gtk/gtktreeview.c | 255 +-
gtk/gtktreeviewcolumn.c | 36 +-
gtk/gtkuimanager.c | 6 +-
gtk/gtkvbbox.c | 80 +-
gtk/gtkvbox.c | 23 +
gtk/gtkviewport.c | 165 +-
gtk/gtkvolumebutton.c | 10 +
gtk/gtkvolumebutton.h | 2 +-
gtk/gtkvpaned.c | 18 +
gtk/gtkvruler.c | 29 +
gtk/gtkvscale.c | 20 +-
gtk/gtkvscale.h | 6 +
gtk/gtkvscrollbar.c | 16 +-
gtk/gtkvscrollbar.h | 6 +
gtk/gtkvseparator.c | 18 +
gtk/gtkvseparator.h | 6 +
gtk/gtkwidget.c | 751 ++-
gtk/gtkwidget.h | 77 +-
gtk/gtkwin32embedwidget.c | 18 +-
gtk/gtkwindow.c | 339 +-
gtk/gtkxembed.c | 4 +-
gtk/paper_names_offsets.c | 165 -
gtk/tests/Makefile.am | 4 +
gtk/tests/action.c | 91 +
gtk/tests/builder.c | 2 +-
gtk/tests/filechooser.c | 48 +-
gtk/tests/testing.c | 2 +-
modules/engines/ms-windows/msw_style.c | 4 +-
modules/other/gail/gail.c | 6 +-
modules/other/gail/gailbooleancell.c | 22 +-
modules/other/gail/gailbooleancell.h | 1 +
modules/other/gail/gailbutton.c | 10 +-
modules/other/gail/gailcell.c | 13 +-
modules/other/gail/gailcheckmenuitem.c | 14 +-
modules/other/gail/gailchecksubmenuitem.c | 14 +-
modules/other/gail/gailcombo.c | 6 +-
modules/other/gail/gailcombobox.c | 6 +-
modules/other/gail/gailentry.c | 4 +-
modules/other/gail/gailexpander.c | 6 +-
modules/other/gail/gailitem.c | 2 +-
modules/other/gail/gaillabel.c | 2 +-
modules/other/gail/gailmenuitem.c | 10 +-
modules/other/gail/gailnotebookpage.c | 2 +-
modules/other/gail/gailoptionmenu.c | 4 +-
modules/other/gail/gailrange.c | 4 +-
modules/other/gail/gailscalebutton.c | 2 +-
modules/other/gail/gailtogglebutton.c | 14 +-
modules/other/gail/gailtoplevel.c | 2 +-
modules/other/gail/gailtreeview.c | 16 +-
modules/other/gail/gailwidget.c | 21 +-
modules/other/gail/gailwindow.c | 6 +-
modules/other/gail/libgail-util/gailmisc.c | 12 +
modules/other/gail/libgail-util/gailtextutil.c | 15 +
modules/other/gail/tests/ferret.c | 2 +-
modules/printbackends/cups/gtkprintbackendcups.c | 34 +
perf/gtkwidgetprofiler.c | 2 +-
po-properties/af.po | 150 +-
po-properties/am.po | 150 +-
po-properties/ang.po | 150 +-
po-properties/ar.po | 150 +-
po-properties/as.po | 150 +-
po-properties/ast.po | 150 +-
po-properties/az.po | 150 +-
po-properties/az_IR.po | 150 +-
po-properties/be.po | 150 +-
po-properties/be latin po | 150 +-
po-properties/bg.po | 234 +-
po-properties/bn.po | 3848 +++++-----
po-properties/bn_IN.po | 3892 +++++-----
po-properties/br.po | 150 +-
po-properties/bs.po | 150 +-
po-properties/ca.po | 3805 +++++-----
po-properties/ca valencia po | 3959 +++++-----
po-properties/crh.po | 378 +-
po-properties/cs.po | 150 +-
po-properties/cy.po | 150 +-
po-properties/da.po | 282 +-
po-properties/de.po | 432 +-
po-properties/dz.po | 150 +-
po-properties/el.po | 384 +-
po-properties/en_CA.po | 150 +-
po-properties/en_GB.po | 268 +-
po-properties/eo.po | 150 +-
po-properties/es.po | 3592 +++++----
po-properties/et.po | 150 +-
po-properties/eu.po | 670 +-
po-properties/fa.po | 150 +-
po-properties/fi.po | 259 +-
po-properties/fr.po | 150 +-
po-properties/ga.po | 150 +-
po-properties/gl.po | 3721 +++++-----
po-properties/gu.po | 150 +-
po-properties/he.po | 150 +-
po-properties/hi.po | 150 +-
po-properties/hr.po | 150 +-
po-properties/hu.po | 278 +-
po-properties/hy.po | 150 +-
po-properties/ia.po | 150 +-
po-properties/id.po | 150 +-
po-properties/io.po | 150 +-
po-properties/is.po | 150 +-
po-properties/it.po | 479 +-
po-properties/ja.po | 150 +-
po-properties/ka.po | 150 +-
po-properties/kk.po | 8603 ++++++++++++++++++++
po-properties/kn.po | 3796 +++++-----
po-properties/ko.po | 311 +-
po-properties/ku.po | 150 +-
po-properties/li.po | 150 +-
po-properties/lt.po | 326 +-
po-properties/lv.po | 150 +-
po-properties/mai.po | 150 +-
po-properties/mi.po | 150 +-
po-properties/mk.po | 150 +-
po-properties/ml.po | 150 +-
po-properties/mn.po | 150 +-
po-properties/mr.po | 3857 +++++-----
po-properties/ms.po | 150 +-
po-properties/my.po | 150 +-
po-properties/nb.po | 150 +-
po-properties/nds.po | 4617 +++++++----
po-properties/ne.po | 150 +-
po-properties/nl.po | 150 +-
po-properties/nn.po | 150 +-
po-properties/nso.po | 150 +-
po-properties/oc.po | 150 +-
po-properties/or.po | 150 +-
po-properties/pa.po | 259 +-
po-properties/pl.po | 359 +-
po-properties/ps.po | 150 +-
po-properties/pt.po | 267 +-
po-properties/pt_BR.po | 150 +-
po-properties/ro.po | 269 +-
po-properties/ru.po | 276 +-
po-properties/rw.po | 150 +-
po-properties/si.po | 150 +-
po-properties/sk.po | 150 +-
po-properties/sl.po | 295 +-
po-properties/sq.po | 150 +-
po-properties/sr.po | 311 +-
po-properties/sr ije po | 150 +-
po-properties/sr latin po | 311 +-
po-properties/sv.po | 235 +-
po-properties/ta.po | 150 +-
po-properties/te.po | 150 +-
po-properties/th.po | 150 +-
po-properties/tk.po | 150 +-
po-properties/tr.po | 150 +-
po-properties/tt.po | 150 +-
po-properties/uk.po | 3658 +++++-----
po-properties/ur.po | 150 +-
po-properties/uz.po | 150 +-
po-properties/uz cyrillic po | 150 +-
po-properties/vi.po | 386 +-
po-properties/wa.po | 150 +-
po-properties/xh.po | 150 +-
po-properties/yi.po | 150 +-
po-properties/zh_CN.po | 150 +-
po-properties/zh_HK.po | 251 +-
po-properties/zh_TW.po | 253 +-
po/LINGUAS | 1 +
po/af.po | 2250 ++----
po/am.po | 824 +--
po/ang.po | 824 +--
po/ar.po | 857 +--
po/as.po | 828 +--
po/ast.po | 828 +--
po/az.po | 828 +--
po/az_IR.po | 824 +--
po/be.po | 828 +--
po/be latin po | 828 +--
po/bg.po | 858 +--
po/bn.po | 3559 ++++-----
po/bn_IN.po | 2522 +++---
po/br.po | 824 +--
po/bs.po | 828 +--
po/ca.po | 984 +--
po/ca valencia po | 3469 +++++----
po/crh.po | 994 +--
po/cs.po | 2401 +++---
po/cy.po | 828 +--
po/da.po | 2476 +++---
po/de.po | 893 +--
po/dz.po | 828 +--
po/el.po | 2453 +++---
po/en_CA.po | 828 +--
po/en_GB.po | 900 +--
po/eo.po | 828 +--
po/es.po | 868 +--
po/et.po | 874 +--
po/eu.po | 1684 ++---
po/fa.po | 828 +--
po/fi.po | 1059 +--
po/fr.po | 827 +--
po/ga.po | 828 +--
po/gl.po | 2713 +++----
po/gu.po | 896 +--
po/he.po | 828 +--
po/hi.po | 828 +--
po/hr.po | 828 +--
po/hu.po | 921 +--
po/hy.po | 828 +--
po/ia.po | 824 +--
po/id.po | 4668 ++++-------
po/io.po | 827 +--
po/is.po | 828 +--
po/it.po | 992 +--
po/ja.po | 837 +--
po/ka.po | 828 +--
po/kk.po | 5336 ++++++++++++
po/kn.po | 2461 +++---
po/ko.po | 950 +--
po/ku.po | 828 +--
po/li.po | 828 +--
po/lt.po | 980 +--
po/lv.po | 3310 ++++----
po/mai.po | 828 +--
po/mi.po | 828 +--
po/mk.po | 828 +--
po/ml.po | 828 +--
po/mn.po | 830 +--
po/mr.po | 2534 +++----
po/ms.po | 828 +--
po/my.po | 828 +--
po/nb.po | 872 +--
po/nds.po | 1307 ++--
po/ne.po | 828 +--
po/nl.po | 903 +--
po/nn.po | 828 +--
po/nso.po | 828 +--
po/oc.po | 825 +--
po/or.po | 847 +--
po/pa.po | 881 +--
po/pl.po | 1261 ++--
po/ps.po | 824 +--
po/pt.po | 902 +--
po/pt_BR.po | 889 +--
po/ro.po | 920 +--
po/ru.po | 957 +--
po/rw.po | 828 +--
po/si.po | 828 +--
po/sk.po | 828 +--
po/sl.po | 898 +--
po/sq.po | 828 +--
po/sr.po | 882 +--
po/sr ije po | 828 +--
po/sr latin po | 882 +--
po/sv.po | 857 +--
po/ta.po | 828 +--
po/te.po | 828 +--
po/th.po | 833 +--
po/tk.po | 824 +--
po/tr.po | 830 +--
po/tt.po | 824 +--
po/uk.po | 3117 +++-----
po/ur.po | 824 +--
po/uz.po | 824 +--
po/uz cyrillic po | 824 +--
po/vi.po | 887 +--
po/wa.po | 828 +--
po/xh.po | 828 +--
po/yi.po | 828 +--
po/zh_CN.po | 828 +--
po/zh_HK.po | 916 +--
po/zh_TW.po | 918 +--
sanitize-la.sh | 5 +-
tests/Makefile.am | 3 +
tests/extendedlayoutexample.c | 620 ++
tests/gtkoffscreenbox.c | 42 +-
tests/multidevice/testphotoalbumwidget.c | 4 +-
tests/testassistant.c | 10 +-
tests/testcalendar.c | 2 +-
tests/testellipsise.c | 121 +-
tests/testgtk.c | 238 +-
tests/testinput.c | 12 +-
tests/testmenubars.c | 12 +-
tests/testmenus.c | 4 +-
tests/testoffscreenwindow.c | 2 +-
tests/testrecentchoosermenu.c | 2 +-
tests/testsocket_common.c | 2 +-
tests/testtext.c | 10 +-
620 files changed, 104620 insertions(+), 104213 deletions(-)
---
diff --cc gdk/gdk.symbols
index f073d0a,bb6e2b2..039ac35
--- a/gdk/gdk.symbols
+++ b/gdk/gdk.symbols
@@@ -717,9 -696,8 +719,10 @@@ gdk_window_freeze_update
gdk_window_get_children
gdk_window_get_internal_paint_info
gdk_window_get_parent
+ gdk_window_get_effective_parent
+#ifndef GDK_MULTIDEVICE_SAFE
gdk_window_get_pointer
+#endif
gdk_window_get_position
gdk_window_get_state
gdk_window_get_toplevel
diff --cc gdk/gdkwindow.c
index 8979de0,e264feb..43f7e74
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@@ -9256,45 -9179,11 +9471,12 @@@ update_cursor (GdkDisplay *display
/* 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);
+ 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);
+ impl_iface->set_device_cursor ((GdkWindow *) toplevel, device,
+ 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,
diff --cc gtk/gtkbutton.c
index bec7a08,37367b3..4ebe9a0
--- a/gtk/gtkbutton.c
+++ b/gtk/gtkbutton.c
@@@ -1752,21 -1718,14 +1719,21 @@@ gtk_real_button_activate (GtkButton *bu
guint32 time;
priv = GTK_BUTTON_GET_PRIVATE (button);
+ device = gtk_get_current_event_device ();
+
+ g_return_if_fail (device && device->source == GDK_SOURCE_KEYBOARD);
- if (GTK_WIDGET_REALIZED (button) && !button->activate_timeout)
+ if (gtk_widget_get_realized (widget) && !button->activate_timeout)
{
time = gtk_get_current_event_time ();
- if (gdk_keyboard_grab (button->event_window, TRUE, time) ==
- GDK_GRAB_SUCCESS)
- {
- priv->has_grab = TRUE;
+
+ if (gdk_device_grab (device, button->event_window,
+ GDK_OWNERSHIP_WINDOW, TRUE,
+ GDK_KEY_PRESS | GDK_KEY_RELEASE,
+ NULL, time) == GDK_GRAB_SUCCESS)
+ {
+ gtk_device_grab_add (widget, device, TRUE);
+ priv->grab_keyboard = device;
priv->grab_time = time;
}
diff --cc gtk/gtkcombobox.c
index fec0d63,fd92dd0..c6b930d
--- a/gtk/gtkcombobox.c
+++ b/gtk/gtkcombobox.c
@@@ -1927,34 -1910,13 +1927,34 @@@ gtk_combo_box_popup_for_device (GtkComb
gint x, y, width, height;
GtkTreePath *path = NULL, *ppath;
GtkWidget *toplevel;
+ GdkDevice *keyboard, *pointer;
+ guint32 time;
+
+ g_return_if_fail (GTK_IS_COMBO_BOX (combo_box));
+ g_return_if_fail (GDK_IS_DEVICE (device));
- if (!GTK_WIDGET_REALIZED (combo_box))
+ if (!gtk_widget_get_realized (GTK_WIDGET (combo_box)))
return;
- if (GTK_WIDGET_MAPPED (priv->popup_widget))
+ if (gtk_widget_get_mapped (priv->popup_widget))
return;
+ if (priv->grab_pointer && priv->grab_keyboard)
+ return;
+
+ time = gtk_get_current_event_time ();
+
+ if (device->source == GDK_SOURCE_KEYBOARD)
+ {
+ keyboard = device;
+ pointer = gdk_device_get_associated_device (device);
+ }
+ else
+ {
+ pointer = device;
+ keyboard = gdk_device_get_associated_device (device);
+ }
+
if (GTK_IS_MENU (priv->popup_widget))
{
gtk_combo_box_menu_popup (combo_box,
@@@ -2076,10 -2011,10 +2076,10 @@@ gtk_combo_box_popdown (GtkComboBox *com
return;
}
- if (!GTK_WIDGET_REALIZED (GTK_WIDGET (combo_box)))
+ if (!gtk_widget_get_realized (GTK_WIDGET (combo_box)))
return;
- gtk_grab_remove (priv->popup_window);
+ gtk_device_grab_remove (priv->popup_window, priv->grab_pointer);
gtk_widget_hide_all (priv->popup_window);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->button),
FALSE);
@@@ -3958,10 -3893,10 +3961,10 @@@ gtk_combo_box_list_button_pressed (GtkW
return FALSE;
if (priv->focus_on_click &&
- !GTK_WIDGET_HAS_FOCUS (priv->button))
+ !gtk_widget_has_focus (priv->button))
gtk_widget_grab_focus (priv->button);
- gtk_combo_box_popup (combo_box);
+ gtk_combo_box_popup_for_device (combo_box, event->device);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->button), TRUE);
diff --cc gtk/gtkentry.c
index 7dc86f5,20653b4..70dc1d7
--- a/gtk/gtkentry.c
+++ b/gtk/gtkentry.c
@@@ -9255,10 -9271,10 +9274,10 @@@ gtk_entry_completion_timeout (gpointer
g_object_get (completion, "popup-single-match", &popup_single, NULL);
if ((matches > (popup_single ? 0: 1)) || actions > 0)
{
- if (GTK_WIDGET_VISIBLE (completion->priv->popup_window))
+ if (gtk_widget_get_visible (completion->priv->popup_window))
_gtk_entry_completion_resize_popup (completion);
else
- _gtk_entry_completion_popup (completion);
+ _gtk_entry_completion_popup (completion, priv->completion_device);
}
else
_gtk_entry_completion_popdown (completion);
diff --cc gtk/gtkentrycompletion.c
index a76cf56,68b758a..e9475fb
--- a/gtk/gtkentrycompletion.c
+++ b/gtk/gtkentrycompletion.c
@@@ -1475,18 -1474,15 +1475,18 @@@ _gtk_entry_completion_popup (GtkEntryCo
GList *renderers;
GtkWidget *toplevel;
- if (GTK_WIDGET_MAPPED (completion->priv->popup_window))
+ if (gtk_widget_get_mapped (completion->priv->popup_window))
return;
- if (!GTK_WIDGET_MAPPED (completion->priv->entry))
+ if (!gtk_widget_get_mapped (completion->priv->entry))
return;
- if (!GTK_WIDGET_HAS_FOCUS (completion->priv->entry))
+ if (!gtk_widget_has_focus (completion->priv->entry))
return;
+ if (completion->priv->grab_device)
+ return;
+
completion->priv->ignore_enter = TRUE;
column = gtk_tree_view_get_column (GTK_TREE_VIEW (completion->priv->action_view), 0);
diff --cc gtk/gtkmain.c
index 5e5eaaf,082eb0f..4f5cc87
--- a/gtk/gtkmain.c
+++ b/gtk/gtkmain.c
@@@ -1514,36 -1524,11 +1515,34 @@@ gtk_main_do_event (GdkEvent *event
gtk_widget_is_ancestor (event_widget, grab_widget))
grab_widget = event_widget;
}
- else
+ else if (device)
+ {
+ grab_widget = gtk_window_group_get_current_device_grab (window_group, device);
+
- if (grab_widget)
- {
- if (GTK_WIDGET_IS_SENSITIVE (event_widget) &&
- gtk_widget_is_ancestor (event_widget, grab_widget))
- grab_widget = event_widget;
- }
++ if (grab_widget &&
++ gtk_widget_get_sensitive (event_widget) &&
++ gtk_widget_is_ancestor (event_widget, grab_widget))
++ grab_widget = event_widget;
+ }
+
+ if (!grab_widget)
+ grab_widget = event_widget;
+
+ /* If the widget receiving events is actually blocked by another device GTK+ grab */
+ if (device &&
+ _gtk_window_group_widget_is_blocked_for_device (window_group, grab_widget, device))
{
- grab_widget = event_widget;
+ if (rewritten_event)
+ gdk_event_free (rewritten_event);
+
+ return;
}
+ /* Push the event onto a stack of current events for
+ * gtk_current_event_get().
+ */
+ current_events = g_list_prepend (current_events, event);
+
/* Not all events get sent to the grabbing widget.
* The delete, destroy, expose, focus change and resize
* events still get sent to the event widget because
@@@ -1664,18 -1649,15 +1663,18 @@@
break;
case GDK_ENTER_NOTIFY:
- GTK_PRIVATE_SET_FLAG (event_widget, GTK_HAS_POINTER);
- _gtk_widget_set_pointer_window (event_widget, event->any.window);
+ _gtk_widget_set_device_window (event_widget,
+ gdk_event_get_device (event),
+ event->any.window);
- if (GTK_WIDGET_IS_SENSITIVE (grab_widget))
+ if (gtk_widget_is_sensitive (grab_widget))
gtk_widget_event (grab_widget, event);
break;
case GDK_LEAVE_NOTIFY:
- GTK_PRIVATE_UNSET_FLAG (event_widget, GTK_HAS_POINTER);
+ _gtk_widget_set_device_window (event_widget,
+ gdk_event_get_device (event),
+ NULL);
- if (GTK_WIDGET_IS_SENSITIVE (grab_widget))
+ if (gtk_widget_is_sensitive (grab_widget))
gtk_widget_event (grab_widget, event);
break;
@@@ -1843,21 -1759,19 +1842,21 @@@ gtk_grab_notify_foreach (GtkWidget *chi
if (is_shadowed)
{
GTK_PRIVATE_SET_FLAG (child, GTK_SHADOWED);
- if (!was_shadowed && GTK_WIDGET_HAS_POINTER (child)
- && gtk_widget_is_sensitive (child))
- _gtk_widget_synthesize_crossing (child, info->new_grab_widget,
- GDK_CROSSING_GTK_GRAB);
+ if (!was_shadowed && devices &&
- GTK_WIDGET_IS_SENSITIVE (child))
++ gtk_widget_is_sensitive (child))
+ synth_crossing_for_grab_notify (child, info->new_grab_widget,
+ info, devices,
+ GDK_CROSSING_GTK_GRAB);
}
else
{
GTK_PRIVATE_UNSET_FLAG (child, GTK_SHADOWED);
- if (was_shadowed && GTK_WIDGET_HAS_POINTER (child)
- && gtk_widget_is_sensitive (child))
- _gtk_widget_synthesize_crossing (info->old_grab_widget, child,
- info->from_grab ? GDK_CROSSING_GTK_GRAB
- : GDK_CROSSING_GTK_UNGRAB);
+ if (was_shadowed && devices &&
- GTK_WIDGET_IS_SENSITIVE (child))
++ gtk_widget_is_sensitive (child))
+ synth_crossing_for_grab_notify (info->old_grab_widget, child,
+ info, devices,
+ info->from_grab ? GDK_CROSSING_GTK_GRAB :
+ GDK_CROSSING_GTK_UNGRAB);
}
if (was_shadowed != is_shadowed)
diff --cc gtk/gtkmenu.c
index eed2feb,b5b9820..995d257
--- a/gtk/gtkmenu.c
+++ b/gtk/gtkmenu.c
@@@ -1406,13 -1395,12 +1406,13 @@@ popup_grab_on_window (GdkWindow *window
}
/**
- * gtk_menu_popup:
+ * gtk_menu_popup_for_device:
* @menu: a #GtkMenu.
- * @device: a #GdkDevice
- * @parent_menu_shell: the menu shell containing the triggering menu item, or %NULL
- * @parent_menu_item: the menu item whose activation triggered the popup, or %NULL
- * @func: a user supplied function used to position the menu, or %NULL
- * @data: user supplied data to be passed to @func.
++ * @device: (allow-none): a #GdkDevice
+ * @parent_menu_shell: (allow-none): the menu shell containing the triggering menu item, or %NULL
+ * @parent_menu_item: (allow-none): the menu item whose activation triggered the popup, or %NULL
+ * @func: (allow-none): a user supplied function used to position the menu, or %NULL
+ * @data: (allow-none): user supplied data to be passed to @func.
* @button: the mouse button which was pressed to initiate the event.
* @activate_time: the time at which the activation event occurred.
*
@@@ -1667,71 -1630,6 +1667,71 @@@ gtk_menu_popup_for_device (GtkMen
_gtk_menu_shell_update_mnemonics (menu_shell);
}
+/**
+ * gtk_menu_popup:
+ * @menu: a #GtkMenu.
- * @parent_menu_shell: the menu shell containing the triggering menu item, or %NULL
- * @parent_menu_item: the menu item whose activation triggered the popup, or %NULL
- * @func: a user supplied function used to position the menu, or %NULL
- * @data: user supplied data to be passed to @func.
++ * @parent_menu_shell: (allow-none): the menu shell containing the triggering menu item, or %NULL
++ * @parent_menu_item: (allow-none): the menu item whose activation triggered the popup, or %NULL
++ * @func: (allow-none): a user supplied function used to position the menu, or %NULL
++ * @data: (allow-none): user supplied data to be passed to @func.
+ * @button: the mouse button which was pressed to initiate the event.
+ * @activate_time: the time at which the activation event occurred.
+ *
+ * Displays a menu and makes it available for selection. Applications can use
+ * this function to display context-sensitive menus, and will typically supply
+ * %NULL for the @parent_menu_shell, @parent_menu_item, @func and @data
+ * parameters. The default menu positioning function will position the menu
+ * at the current mouse cursor position.
+ *
+ * The @button parameter should be the mouse button pressed to initiate
+ * the menu popup. If the menu popup was initiated by something other than
+ * a mouse button press, such as a mouse button release or a keypress,
+ * @button should be 0.
+ *
+ * The @activate_time parameter is used to conflict-resolve initiation of
+ * concurrent requests for mouse/keyboard grab requests. To function
+ * properly, this needs to be the time stamp of the user event (such as
+ * a mouse click or key press) that caused the initiation of the popup.
+ * Only if no such event is available, gtk_get_current_event_time() can
+ * be used instead.
+ */
+void
+gtk_menu_popup (GtkMenu *menu,
+ GtkWidget *parent_menu_shell,
+ GtkWidget *parent_menu_item,
+ GtkMenuPositionFunc func,
+ gpointer data,
+ guint button,
+ guint32 activate_time)
+{
+ GdkDevice *device;
+
+ g_return_if_fail (GTK_IS_MENU (menu));
+
+ device = gtk_get_current_event_device ();
+
+ if (!device)
+ {
+ GdkDisplay *display;
+ GdkDeviceManager *device_manager;
+ GList *devices;
+
+ display = gtk_widget_get_display (GTK_WIDGET (menu));
+ device_manager = gdk_display_get_device_manager (display);
+ devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
+
+ device = devices->data;
+
+ g_list_free (devices);
+ }
+
+ gtk_menu_popup_for_device (menu, device,
+ parent_menu_shell,
+ parent_menu_item,
+ func, data,
+ button, activate_time);
+}
+
void
gtk_menu_popdown (GtkMenu *menu)
{
@@@ -4081,11 -3972,9 +4084,11 @@@ gtk_menu_stop_navigating_submenu_cb (gp
gtk_menu_stop_navigating_submenu (menu);
- if (GTK_WIDGET_REALIZED (menu))
+ if (gtk_widget_get_realized (GTK_WIDGET (menu)))
{
- child_window = gdk_window_get_pointer (menu->bin_window, NULL, NULL, NULL);
+ child_window = gdk_window_get_device_position (menu->bin_window,
+ popdown_data->device,
+ NULL, NULL, NULL);
if (child_window)
{
diff --cc gtk/gtkmenushell.c
index da94b60,c3e107f..615f9a4
--- a/gtk/gtkmenushell.c
+++ b/gtk/gtkmenushell.c
@@@ -135,11 -135,12 +135,15 @@@ struct _GtkMenuShellPrivat
GtkMnemonicHash *mnemonic_hash;
GtkKeyHash *key_hash;
+ GdkDevice *grab_keyboard;
+ GdkDevice *grab_pointer;
+
guint take_focus : 1;
guint activated_submenu : 1;
+ /* This flag is a crutch to keep mnemonics in the same menu
+ * if the user moves the mouse over an unselectable menuitem.
+ */
+ guint in_unselectable_item : 1;
};
static void gtk_menu_shell_set_property (GObject *object,
diff --cc gtk/gtkprivate.h
index ded69e0,4c5efb3..8db5c48
--- a/gtk/gtkprivate.h
+++ b/gtk/gtkprivate.h
@@@ -35,18 -35,22 +35,21 @@@ G_BEGIN_DECL
*/
typedef enum
{
- PRIVATE_GTK_USER_STYLE = 1 << 0,
- PRIVATE_GTK_RESIZE_PENDING = 1 << 2,
- PRIVATE_GTK_SHADOWED = 1 << 4, /* If there is a grab in effect shadowing the widget */
- PRIVATE_GTK_HAS_SHAPE_MASK = 1 << 5,
- PRIVATE_GTK_IN_REPARENT = 1 << 6,
- PRIVATE_GTK_DIRECTION_SET = 1 << 7, /* If the reading direction is not DIR_NONE */
- PRIVATE_GTK_DIRECTION_LTR = 1 << 8, /* If the reading direction is DIR_LTR */
- PRIVATE_GTK_ANCHORED = 1 << 9, /* If widget has a GtkWindow ancestor */
- PRIVATE_GTK_CHILD_VISIBLE = 1 << 10, /* If widget should be mapped when parent is mapped */
- PRIVATE_GTK_REDRAW_ON_ALLOC = 1 << 11, /* If we should queue a draw on the entire widget when it is reallocated */
- PRIVATE_GTK_ALLOC_NEEDED = 1 << 12, /* If we we should allocate even if the allocation is the same */
- PRIVATE_GTK_REQUEST_NEEDED = 1 << 13 /* Whether we need to call gtk_widget_size_request */
+ PRIVATE_GTK_USER_STYLE = 1 << 0,
+ PRIVATE_GTK_RESIZE_PENDING = 1 << 2,
+ PRIVATE_GTK_HAS_POINTER = 1 << 3, /* If the pointer is above a window belonging to the widget */
+ PRIVATE_GTK_SHADOWED = 1 << 4, /* If there is a grab in effect shadowing the widget */
+ PRIVATE_GTK_HAS_SHAPE_MASK = 1 << 5,
+ PRIVATE_GTK_IN_REPARENT = 1 << 6,
+ PRIVATE_GTK_DIRECTION_SET = 1 << 7, /* If the reading direction is not DIR_NONE */
+ PRIVATE_GTK_DIRECTION_LTR = 1 << 8, /* If the reading direction is DIR_LTR */
+ PRIVATE_GTK_ANCHORED = 1 << 9, /* If widget has a GtkWindow ancestor */
+ PRIVATE_GTK_CHILD_VISIBLE = 1 << 10, /* If widget should be mapped when parent is mapped */
+ PRIVATE_GTK_REDRAW_ON_ALLOC = 1 << 11, /* If we should queue a draw on the entire widget when it is reallocated */
+ PRIVATE_GTK_ALLOC_NEEDED = 1 << 12, /* If we we should allocate even if the allocation is the same */
+ PRIVATE_GTK_REQUEST_NEEDED = 1 << 13, /* Whether we need to call gtk_widget_size_request */
+ PRIVATE_GTK_WIDTH_REQUEST_NEEDED = 1 << 14, /* Whether we need to call gtk_extended_layout_get_desired_width */
+ PRIVATE_GTK_HEIGHT_REQUEST_NEEDED = 1 << 15 /* Whether we need to call gtk_extended_layout_get_desired_height */
-
} GtkPrivateFlags;
/* Macros for extracting a widgets private_flags from GtkWidget.
diff --cc gtk/gtkrange.c
index 6d0875b,552eac7..ffbefe8
--- a/gtk/gtkrange.c
+++ b/gtk/gtkrange.c
@@@ -2207,9 -2180,8 +2206,9 @@@ gtk_range_button_press (GtkWidget
GdkEventButton *event)
{
GtkRange *range = GTK_RANGE (widget);
+ GdkDevice *device;
- if (!GTK_WIDGET_HAS_FOCUS (widget))
+ if (!gtk_widget_has_focus (widget))
gtk_widget_grab_focus (widget);
/* ignore presses when we're already doing something else. */
diff --cc gtk/gtktextview.c
index e6b830c,e286101..b4aa731
--- a/gtk/gtktextview.c
+++ b/gtk/gtktextview.c
@@@ -109,7 -109,7 +109,8 @@@ struct _GtkTextViewPrivat
guint blink_time; /* time in msec the cursor has blinked since last user event */
guint im_spot_idle;
gchar *im_module;
+ GdkDevice *grab_device;
+ guint scroll_after_paste : 1;
};
diff --cc gtk/gtktreeview.c
index 2d5064b,f464ec4..6b517bc
--- a/gtk/gtktreeview.c
+++ b/gtk/gtktreeview.c
@@@ -10267,54 -10264,17 +10271,43 @@@ gtk_tree_view_search_entry_flush_timeou
/* Cut and paste from gtkwindow.c */
static void
send_focus_change (GtkWidget *widget,
+ GdkDevice *device,
gboolean in)
{
- GdkEvent *fevent = gdk_event_new (GDK_FOCUS_CHANGE);
+ GdkDeviceManager *device_manager;
+ GList *devices, *d;
- g_object_ref (widget);
-
- if (in)
- GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
- else
- GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
-
- fevent->focus_change.type = GDK_FOCUS_CHANGE;
- fevent->focus_change.window = g_object_ref (gtk_widget_get_window (widget));
- fevent->focus_change.in = in;
+ device_manager = gdk_display_get_device_manager (gtk_widget_get_display (widget));
+ devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
+ devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_SLAVE));
+ devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_FLOATING));
- gtk_widget_send_focus_change (widget, fevent);
+ for (d = devices; d; d = d->next)
+ {
+ GdkDevice *dev = d->data;
+ GdkEvent *fevent;
- gdk_event_free (fevent);
+ if (dev->source != GDK_SOURCE_KEYBOARD)
+ continue;
+
+ /* Skip non-master keyboards that haven't
+ * selected for events from this window
+ */
+ if (gdk_device_get_device_type (dev) != GDK_DEVICE_TYPE_MASTER &&
+ !gdk_window_get_device_events (widget->window, dev))
+ continue;
+
+ fevent = gdk_event_new (GDK_FOCUS_CHANGE);
+
+ fevent->focus_change.type = GDK_FOCUS_CHANGE;
+ fevent->focus_change.window = g_object_ref (widget->window);
+ fevent->focus_change.in = in;
+ gdk_event_set_device (fevent, device);
+
- gtk_widget_event (widget, fevent);
++ gtk_widget_send_focus_change (widget, fevent);
+
+ gdk_event_free (fevent);
+ }
-
- g_object_notify (G_OBJECT (widget), "has-focus");
-
- g_object_unref (widget);
}
static void
@@@ -14207,13 -14163,13 +14200,13 @@@ gtk_tree_view_search_dialog_hide (GtkWi
tree_view->priv->typeselect_flush_timeout = 0;
}
- if (GTK_WIDGET_VISIBLE (search_dialog))
+ if (gtk_widget_get_visible (search_dialog))
{
/* send focus-in event */
- send_focus_change (GTK_WIDGET (tree_view->priv->search_entry), FALSE);
+ send_focus_change (GTK_WIDGET (tree_view->priv->search_entry), device, FALSE);
gtk_widget_hide (search_dialog);
gtk_entry_set_text (GTK_ENTRY (tree_view->priv->search_entry), "");
- send_focus_change (GTK_WIDGET (tree_view), TRUE);
+ send_focus_change (GTK_WIDGET (tree_view), device, TRUE);
}
}
diff --cc gtk/gtkwidget.c
index 6125eb6,b27207c..d862aaf
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@@ -5826,60 -5758,6 +5882,60 @@@ _gtk_widget_set_has_grab (GtkWidget *wi
}
/**
+ * gtk_widget_device_is_shadowed:
+ * @widget: a #GtkWidget
+ * @device: a #GdkDevice
+ *
+ * Returns %TRUE if @device has been shadowed by a GTK+
+ * device grab on another widget, so it would stop sending
+ * events to @widget. This may be used in the
+ * #GtkWidget::grab-notify signal to check for specific
+ * devices. See gtk_device_grab_add().
+ *
+ * Returns: %TRUE if there is an ongoing grab on @device
+ * by another #GtkWidget than @widget.
+ **/
+gboolean
+gtk_widget_device_is_shadowed (GtkWidget *widget,
+ GdkDevice *device)
+{
+ GtkWindowGroup *group;
+ GtkWidget *grab_widget, *toplevel;
+
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
+ g_return_val_if_fail (GDK_IS_DEVICE (device), FALSE);
+
- if (!GTK_WIDGET_REALIZED (widget))
++ if (!gtk_widget_get_realized (widget))
+ return TRUE;
+
+ toplevel = gtk_widget_get_toplevel (widget);
+
+ if (GTK_IS_WINDOW (toplevel))
+ group = gtk_window_get_group (GTK_WINDOW (toplevel));
+ else
+ group = gtk_window_get_group (NULL);
+
+ grab_widget = gtk_window_group_get_current_device_grab (group, device);
+
+ /* Widget not inside the hierarchy of grab_widget */
+ if (grab_widget &&
+ widget != grab_widget &&
+ !gtk_widget_is_ancestor (widget, grab_widget))
+ return TRUE;
+
+ if (group->grabs)
+ {
+ grab_widget = group->grabs->data;
+
+ if (widget != grab_widget &&
+ !gtk_widget_is_ancestor (widget, grab_widget))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
* gtk_widget_set_name:
* @widget: a #GtkWidget
* @name: name for the widget
@@@ -9066,36 -8972,18 +9151,36 @@@ _gtk_widget_peek_colormap (void
* Actually stores it on the #GdkScreen, but you don't need to know that.
*/
void
-_gtk_widget_set_pointer_window (GtkWidget *widget,
- GdkWindow *pointer_window)
+_gtk_widget_set_device_window (GtkWidget *widget,
+ GdkDevice *device,
+ GdkWindow *window)
{
+ GdkScreen *screen;
+ GHashTable *device_window;
+
g_return_if_fail (GTK_IS_WIDGET (widget));
+ g_return_if_fail (GDK_IS_DEVICE (device));
+ g_return_if_fail (!window || GDK_IS_WINDOW (window));
- if (!GTK_WIDGET_REALIZED (widget))
- if (gtk_widget_get_realized (widget))
- {
- GdkScreen *screen = gdk_drawable_get_screen (widget->window);
++ if (!gtk_widget_get_realized (widget))
+ return;
- g_object_set_qdata (G_OBJECT (screen), quark_pointer_window,
- pointer_window);
+ screen = gdk_drawable_get_screen (widget->window);
+ device_window = g_object_get_qdata (G_OBJECT (screen), quark_pointer_window);
+
+ if (G_UNLIKELY (!device_window))
+ {
+ device_window = g_hash_table_new (NULL, NULL);
+ g_object_set_qdata_full (G_OBJECT (screen),
+ quark_pointer_window,
+ device_window,
+ (GDestroyNotify) g_hash_table_destroy);
}
+
+ if (window)
+ g_hash_table_insert (device_window, device, window);
+ else
+ g_hash_table_remove (device_window, device);
}
/*
@@@ -9107,85 -8994,18 +9192,85 @@@
* to, or %NULL.
*/
GdkWindow *
-_gtk_widget_get_pointer_window (GtkWidget *widget)
+_gtk_widget_get_device_window (GtkWidget *widget,
+ GdkDevice *device)
{
+ GdkScreen *screen;
+ GHashTable *device_window;
+ GdkWindow *window;
+ GtkWidget *w;
+
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
+ g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
- if (!GTK_WIDGET_REALIZED (widget))
- if (gtk_widget_get_realized (widget))
++ if (!gtk_widget_get_realized (widget))
+ return NULL;
+
+ screen = gdk_drawable_get_screen (widget->window);
+ device_window = g_object_get_qdata (G_OBJECT (screen), quark_pointer_window);
+
+ if (G_UNLIKELY (!device_window))
+ return NULL;
+
+ window = g_hash_table_lookup (device_window, device);
+
+ if (!window)
+ return NULL;
+
+ gdk_window_get_user_data (window, (gpointer *) &w);
+
+ if (widget != w)
+ return NULL;
+
+ return window;
+}
+
+/*
+ * _gtk_widget_list_devices:
+ * @widget: a #GtkWidget.
+ *
+ * Returns the list of #GdkDevices that is currently on top of any widget #GdkWindow.
+ * Free the list with g_list_free(), the elements are owned by GTK+ and must not
+ * be freed.
+ */
+GList *
+_gtk_widget_list_devices (GtkWidget *widget)
+{
+ GdkScreen *screen;
+ GHashTableIter iter;
+ GHashTable *device_window;
+ GList *devices = NULL;
+ gpointer key, value;
+
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
+
- if (!GTK_WIDGET_REALIZED (widget))
++ if (!gtk_widget_get_realized (widget))
+ return NULL;
+
+ screen = gdk_drawable_get_screen (widget->window);
+ device_window = g_object_get_qdata (G_OBJECT (screen), quark_pointer_window);
+
+ if (G_UNLIKELY (!device_window))
+ return NULL;
+
+ g_hash_table_iter_init (&iter, device_window);
+
+ while (g_hash_table_iter_next (&iter, &key, &value))
{
- GdkScreen *screen = gdk_drawable_get_screen (widget->window);
+ GdkDevice *device = key;
+ GdkWindow *window = value;
+ GtkWidget *w;
- return g_object_get_qdata (G_OBJECT (screen), quark_pointer_window);
+ if (window)
+ {
+ gdk_window_get_user_data (window, (gpointer *) &w);
+
+ if (widget == w)
+ devices = g_list_prepend (devices, device);
+ }
}
- return NULL;
+ return devices;
}
static void
@@@ -9466,41 -9300,15 +9551,41 @@@ gtk_widget_propagate_state (GtkWidge
g_signal_emit (widget, widget_signals[STATE_CHANGED], 0, old_state);
- if (GTK_WIDGET_HAS_POINTER (widget) && !GTK_WIDGET_SHADOWED (widget))
- {
- if (!gtk_widget_is_sensitive (widget))
- _gtk_widget_synthesize_crossing (widget, NULL,
- GDK_CROSSING_STATE_CHANGED);
- else if (old_state == GTK_STATE_INSENSITIVE)
- _gtk_widget_synthesize_crossing (NULL, widget,
- GDK_CROSSING_STATE_CHANGED);
- }
+ if (!GTK_WIDGET_SHADOWED (widget))
+ {
+ GList *event_windows = NULL;
+ GList *devices, *d;
+
+ devices = _gtk_widget_list_devices (widget);
+
+ for (d = devices; d; d = d->next)
+ {
+ GdkWindow *window;
+ GdkDevice *device;
+
+ device = d->data;
+ window = _gtk_widget_get_device_window (widget, device);
+
+ /* Do not propagate more than once to the
+ * same window if non-multidevice aware.
+ */
+ if (!gdk_window_get_support_multidevice (window) &&
+ g_list_find (event_windows, window))
+ continue;
+
- if (!GTK_WIDGET_IS_SENSITIVE (widget))
++ if (!gtk_widget_is_sensitive (widget))
+ _gtk_widget_synthesize_crossing (widget, NULL, d->data,
+ GDK_CROSSING_STATE_CHANGED);
+ else if (old_state == GTK_STATE_INSENSITIVE)
+ _gtk_widget_synthesize_crossing (NULL, widget, d->data,
+ GDK_CROSSING_STATE_CHANGED);
+
+ event_windows = g_list_prepend (event_windows, window);
+ }
+
+ g_list_free (event_windows);
+ g_list_free (devices);
+ }
if (GTK_IS_CONTAINER (widget))
{
@@@ -11529,304 -11421,71 +11698,370 @@@ gtk_widget_get_window (GtkWidget *widge
return widget->window;
}
+/**
+ * gtk_widget_get_support_multidevice:
+ * @widget: a #GtkWidget
+ *
+ * Returns %TRUE if @widget is multiple pointer aware. See
+ * gtk_widget_set_support_multidevice() for more information.
+ *
+ * Returns: %TRUE is @widget is multidevice aware.
+ **/
+gboolean
+gtk_widget_get_support_multidevice (GtkWidget *widget)
+{
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
+
+ return GTK_WIDGET_FLAGS (widget) & GTK_MULTIDEVICE;
+}
+
+/**
+ * gtk_widget_set_support_multidevice:
+ * @widget: a #GtkWidget
+ * @support_multidevice: %TRUE to support input from multiple devices.
+ *
+ * Enables or disables multiple pointer awareness. If this setting is %TRUE,
+ * @widget will start receiving multiple, per device enter/leave events. Note
+ * that if custom #GdkWindow<!-- -->s are created in #GtkWidget::realize,
+ * gdk_window_set_support_multidevice() will have to be called manually on them.
+ **/
+void
+gtk_widget_set_support_multidevice (GtkWidget *widget,
+ gboolean support_multidevice)
+{
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+
+ if (support_multidevice)
+ {
+ GTK_WIDGET_SET_FLAGS (widget, GTK_MULTIDEVICE);
+ gtk_widget_set_extension_events (widget, GDK_EXTENSION_EVENTS_ALL);
+ }
+ else
+ {
+ GTK_WIDGET_UNSET_FLAGS (widget, GTK_MULTIDEVICE);
+ gtk_widget_set_extension_events (widget, GDK_EXTENSION_EVENTS_NONE);
+ }
+
- if (GTK_WIDGET_REALIZED (widget))
++ if (gtk_widget_get_realized (widget))
+ gdk_window_set_support_multidevice (widget->window, support_multidevice);
+}
+
+static GdkEventMotion *
+convert_event_to_motion (GdkEvent *event)
+{
+ GdkEventMotion *new_event;
+
+ new_event = (GdkEventMotion *) gdk_event_new (GDK_MOTION_NOTIFY);
+
+ switch (event->type)
+ {
+ case GDK_BUTTON_PRESS:
+ case GDK_2BUTTON_PRESS:
+ case GDK_3BUTTON_PRESS:
+ case GDK_BUTTON_RELEASE:
+ new_event->window = g_object_ref (event->button.window);
+ new_event->send_event = TRUE;
+ new_event->time = event->button.time;
+ new_event->x = event->button.x;
+ new_event->y = event->button.y;
+
+ if (event->button.axes)
+ new_event->axes = g_memdup (event->button.axes,
+ sizeof (gdouble) * event->button.device->num_axes);
+
+ new_event->state = 0; /* FIXME */
+ new_event->is_hint = FALSE;
+ new_event->device = event->button.device;
+ new_event->x_root = event->button.x_root;
+ new_event->y_root = event->button.y_root;
+ break;
+ case GDK_ENTER_NOTIFY:
+ case GDK_LEAVE_NOTIFY:
+ new_event->window = g_object_ref (event->crossing.window);
+ new_event->send_event = TRUE;
+ new_event->time = event->crossing.time;
+ new_event->x = event->crossing.x;
+ new_event->y = event->crossing.y;
+ new_event->axes = NULL; /* FIXME: not ideal for non-mice */
+ new_event->state = 0; /* FIXME */
+ new_event->is_hint = FALSE;
+ new_event->x_root = event->crossing.x_root;
+ new_event->y_root = event->crossing.y_root;
+ gdk_event_set_device ((GdkEvent *) new_event, gdk_event_get_device ((GdkEvent *) event));
+ break;
+ default:
+ g_warning ("Event with type %d can not be transformed to GdkEventMotion", event->type);
+ gdk_event_free ((GdkEvent *) new_event);
+ new_event = NULL;
+ }
+
+ return new_event;
+}
+
+static void
+device_group_device_added (GtkDeviceGroup *group,
+ GdkDevice *device,
+ GtkWidget *widget)
+{
+ GtkMultiDeviceData *data;
+ GtkDeviceGroup *old_group;
+ GdkEventMotion *new_event = NULL;
+ GtkWidget *event_widget;
+ GdkEvent *event;
+
+ data = g_object_get_qdata (G_OBJECT (widget), quark_multidevice_data);
+
+ if (G_UNLIKELY (!data))
+ return;
+
+ /* Remove device from old group, if any */
+ old_group = g_hash_table_lookup (data->by_dev, device);
+
+ if (old_group)
+ gtk_device_group_remove_device (old_group, device);
+
+ g_hash_table_insert (data->by_dev,
+ g_object_ref (device),
+ g_object_ref (group));
+
+ event = gtk_get_current_event ();
+
+ if (!event)
+ return;
+
+ if (event->type == GDK_MOTION_NOTIFY)
+ new_event = (GdkEventMotion *) event;
+ else
+ {
+ event_widget = gtk_get_event_widget (event);
+
+ if (widget == event_widget)
+ new_event = convert_event_to_motion (event);
+
+ gdk_event_free (event);
+ }
+
+ if (new_event)
+ {
+ gtk_widget_event_internal (widget, (GdkEvent *) new_event);
+ gdk_event_free ((GdkEvent *) new_event);
+ }
+}
+
+static void
+device_group_device_removed (GtkDeviceGroup *group,
+ GdkDevice *device,
+ GtkWidget *widget)
+{
+ GtkMultiDeviceData *data;
+
+ data = g_object_get_qdata (G_OBJECT (widget), quark_multidevice_data);
+
+ g_assert (data != NULL);
+
+ compose_multidevice_event (widget, device, NULL);
+ g_hash_table_remove (data->by_dev, device);
+}
+
+static void
+free_multidevice_data (GtkMultiDeviceData *data)
+{
+ g_list_foreach (data->groups, (GFunc) g_object_unref, NULL);
+ g_list_free (data->groups);
+
+ g_hash_table_destroy (data->by_dev);
+
+ g_slice_free (GtkMultiDeviceData, data);
+}
+
+/**
+ * gtk_widget_create_device_group:
+ * @widget: a #GtkWidget
+ *
+ * Creates a new #GtkDeviceGroup for @widget. devices can be added
+ * later through gtk_device_group_add_device(). Note that
+ * #GdkDevice<!-- -->s can only pertain to one #GtkDeviceGroup for a
+ * given #GtkWidget, so adding it to a new group will remove it from
+ * its previous one.
+ *
+ * Returns: a newly created #GtkDeviceGroup. This object is owned by
+ * @widget and must be destroyed through
+ * gtk_widget_remove_device_group().
+ **/
+GtkDeviceGroup *
+gtk_widget_create_device_group (GtkWidget *widget)
+{
+ GtkMultiDeviceData *data;
+ GtkDeviceGroup *group;
+
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
+
+ group = g_object_new (GTK_TYPE_DEVICE_GROUP, NULL);
+
+ g_signal_connect (group, "device-added",
+ G_CALLBACK (device_group_device_added), widget);
+ g_signal_connect (group, "device-removed",
+ G_CALLBACK (device_group_device_removed), widget);
+
+ data = g_object_get_qdata (G_OBJECT (widget), quark_multidevice_data);
+
+ if (G_UNLIKELY (!data))
+ {
+ data = g_slice_new0 (GtkMultiDeviceData);
+ data->by_dev = g_hash_table_new_full (g_direct_hash,
+ g_direct_equal,
+ (GDestroyNotify) g_object_unref,
+ (GDestroyNotify) g_object_unref);
+
+ g_object_set_qdata_full (G_OBJECT (widget),
+ quark_multidevice_data,
+ data,
+ (GDestroyNotify) free_multidevice_data);
+ }
+
+ data->groups = g_list_prepend (data->groups, group);
+
+ return group;
+}
+
+/**
+ * gtk_widget_remove_device_group:
+ * @widget: a #GtkWidget
+ * @group: a #GtkDeviceGroup
+ *
+ * If @group pertains to @widget, @group will be destroyed so no further
+ * #GtkWidget::multidevice-event<!-- -->s are emitted for it.
+ **/
+void
+gtk_widget_remove_device_group (GtkWidget *widget,
+ GtkDeviceGroup *group)
+{
+ GtkMultiDeviceData *data;
+ GList *devices, *g;
+
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+ g_return_if_fail (GTK_IS_DEVICE_GROUP (group));
+
+ data = g_object_get_qdata (G_OBJECT (widget), quark_multidevice_data);
+
+ if (G_UNLIKELY (!data))
+ return;
+
+ g = g_list_find (data->groups, group);
+
+ if (G_UNLIKELY (!g))
+ return;
+
+ devices = gtk_device_group_get_devices (group);
+
+ /* Free per-device data */
+ while (devices)
+ {
+ g_hash_table_remove (data->by_dev, devices->data);
+ devices = devices->next;
+ }
+
+ /* Free group */
+ data->groups = g_list_remove_link (data->groups, g);
+ g_object_unref (g->data);
+ g_list_free_1 (g);
+}
+
+/**
+ * gtk_widget_get_group_for_device:
+ * @widget: a #GtkWidget
+ * @device: a #GdkDevice
+ *
+ * Returns the #GtkDeviceGroup containing the #GdkDevice, or %NULL if
+ * there is none.
+ *
+ * Returns: a #GtkDeviceGroup, or %NULL.
+ **/
+GtkDeviceGroup *
+gtk_widget_get_group_for_device (GtkWidget *widget,
+ GdkDevice *device)
+{
+ GtkMultiDeviceData *data;
+ GtkDeviceGroup *group = NULL;
+
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
+ g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
+
+ data = g_object_get_qdata (G_OBJECT (widget), quark_multidevice_data);
+
+ if (!data)
+ return NULL;
+
+ group = g_hash_table_lookup (data->by_dev, device);
+
+ return group;
+}
+
+ static void
+ _gtk_widget_set_has_focus (GtkWidget *widget,
+ gboolean has_focus)
+ {
+ if (has_focus)
+ GTK_OBJECT_FLAGS (widget) |= GTK_HAS_FOCUS;
+ else
+ GTK_OBJECT_FLAGS (widget) &= ~(GTK_HAS_FOCUS);
+ }
+
+ /**
+ * gtk_widget_send_focus_change:
+ * @widget: a #GtkWidget
+ * @event: a #GdkEvent of type GDK_FOCUS_CHANGE
+ *
+ * Sends the focus change @event to @widget
+ *
+ * This function is not meant to be used by applications. The only time it
+ * should be used is when it is necessary for a #GtkWidget to assign focus
+ * to a widget that is semantically owned by the first widget even though
+ * it's not a direct child - for instance, a search entry in a floating
+ * window similar to the quick search in #GtkTreeView.
+ *
+ * An example of its usage is:
+ *
+ * |[
+ * GdkEvent *fevent = gdk_event_new (GDK_FOCUS_CHANGE);
+ *
+ * fevent->focus_change.type = GDK_FOCUS_CHANGE;
+ * fevent->focus_change.in = TRUE;
+ * fevent->focus_change.window = gtk_widget_get_window (widget);
+ * if (fevent->focus_change.window != NULL)
+ * g_object_ref (fevent->focus_change.window);
+ *
+ * gtk_widget_send_focus_change (widget, fevent);
+ *
+ * gdk_event_free (event);
+ * ]|
+ *
+ * Return value: the return value from the event signal emission: %TRUE
+ * if the event was handled, and %FALSE otherwise
+ *
+ * Since: 2.20
+ */
+ gboolean
+ gtk_widget_send_focus_change (GtkWidget *widget,
+ GdkEvent *event)
+ {
+ gboolean res;
+
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
+ g_return_val_if_fail (event != NULL && event->type == GDK_FOCUS_CHANGE, FALSE);
+
+ g_object_ref (widget);
+
+ _gtk_widget_set_has_focus (widget, event->focus_change.in);
+
+ res = gtk_widget_event (widget, event);
+
+ g_object_notify (G_OBJECT (widget), "has-focus");
+
+ g_object_unref (widget);
+
+ return res;
+ }
+
#define __GTK_WIDGET_C__
#include "gtkaliasdef.c"
diff --cc gtk/gtkwidget.h
index 94be39a,760d7ce..7ffa394
--- a/gtk/gtkwidget.h
+++ b/gtk/gtkwidget.h
@@@ -429,8 -481,8 +483,9 @@@ typedef struct _GtkWidgetShapeInfo GtkW
typedef struct _GtkClipboard GtkClipboard;
typedef struct _GtkTooltip GtkTooltip;
typedef struct _GtkWindow GtkWindow;
+typedef struct _GtkMultiDeviceEvent GtkMultiDeviceEvent;
+
/**
* GtkAllocation:
* @x: the X position of the widget's area relative to its parents allocation.
diff --cc gtk/gtkwindow.c
index fcc100f,1af7d02..307ffbc
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@@ -5287,53 -5262,17 +5278,42 @@@ static voi
do_focus_change (GtkWidget *widget,
gboolean in)
{
- GdkEvent *fevent = gdk_event_new (GDK_FOCUS_CHANGE);
-
- fevent->focus_change.type = GDK_FOCUS_CHANGE;
- fevent->focus_change.window = widget->window;
- fevent->focus_change.in = in;
- if (widget->window)
- g_object_ref (widget->window);
+ GdkDeviceManager *device_manager;
+ GList *devices, *d;
+
- g_object_ref (widget);
-
- if (in)
- GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
- else
- GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
-
+ device_manager = gdk_display_get_device_manager (gtk_widget_get_display (widget));
+ devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
+ devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_SLAVE));
+ devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_FLOATING));
+
+ for (d = devices; d; d = d->next)
+ {
+ GdkDevice *dev = d->data;
+ GdkEvent *fevent;
- gtk_widget_send_focus_change (widget, fevent);
+ if (dev->source != GDK_SOURCE_KEYBOARD)
+ continue;
- gdk_event_free (fevent);
+ /* Skip non-master keyboards that haven't
+ * selected for events from this window
+ */
+ if (gdk_device_get_device_type (dev) != GDK_DEVICE_TYPE_MASTER &&
+ !gdk_window_get_device_events (widget->window, dev))
+ continue;
+
+ fevent = gdk_event_new (GDK_FOCUS_CHANGE);
+
+ fevent->focus_change.type = GDK_FOCUS_CHANGE;
+ fevent->focus_change.window = widget->window;
+ if (widget->window)
+ g_object_ref (widget->window);
+ fevent->focus_change.in = in;
+ gdk_event_set_device (fevent, dev);
+
- gtk_widget_event (widget, fevent);
++ gtk_widget_send_focus_change (widget, fevent);
+
+ gdk_event_free (fevent);
+ }
-
- g_object_notify (G_OBJECT (widget), "has-focus");
-
- g_object_unref (widget);
}
static gint
diff --cc tests/multidevice/testphotoalbumwidget.c
index dbd6eb4,0000000..b530069
mode 100644,000000..100644
--- a/tests/multidevice/testphotoalbumwidget.c
+++ b/tests/multidevice/testphotoalbumwidget.c
@@@ -1,508 -1,0 +1,508 @@@
+/*
+ * Copyright (C) 2009 Carlos Garnacho <carlosg gnome org>
+ *
+ * This work is provided "as is"; redistribution and modification
+ * in whole or in part, in any medium, physical or electronic is
+ * permitted without restriction.
+ *
+ * This work 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.
+ *
+ * In no event shall the authors or contributors be liable for any
+ * direct, indirect, incidental, special, exemplary, or consequential
+ * damages (including, but not limited to, procurement of substitute
+ * goods or services; loss of use, data, or profits; or business
+ * interruption) however caused and on any theory of liability, whether
+ * in contract, strict liability, or tort (including negligence or
+ * otherwise) arising in any way out of the use of this software, even
+ * if advised of the possibility of such damage.
+ */
+
+#include "testphotoalbumwidget.h"
+#include <math.h>
+
+#define TEST_PHOTO_ALBUM_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TEST_TYPE_PHOTO_ALBUM_WIDGET, TestPhotoAlbumWidgetPrivate))
+
+typedef struct TestPhotoAlbumWidgetPrivate TestPhotoAlbumWidgetPrivate;
+typedef struct TestPhoto TestPhoto;
+
+struct TestPhoto
+{
+ GdkPixbuf *pixbuf;
+ GtkDeviceGroup *group;
+ gdouble center_x;
+ gdouble center_y;
+ gdouble x;
+ gdouble y;
+ gdouble angle;
+ gdouble zoom;
+
+ GdkRegion *region;
+
+ gdouble base_zoom;
+ gdouble base_angle;
+ gdouble initial_distance;
+ gdouble initial_angle;
+};
+
+struct TestPhotoAlbumWidgetPrivate
+{
+ GPtrArray *photos;
+};
+
+static GQuark quark_group_photo = 0;
+
+
+static void test_photo_album_widget_class_init (TestPhotoAlbumWidgetClass *klass);
+static void test_photo_album_widget_init (TestPhotoAlbumWidget *album);
+
+static void test_photo_album_widget_destroy (GtkObject *object);
+
+static gboolean test_photo_album_widget_button_press (GtkWidget *widget,
+ GdkEventButton *event);
+static gboolean test_photo_album_widget_button_release (GtkWidget *widget,
+ GdkEventButton *event);
+static void test_photo_album_widget_multidevice_event (GtkWidget *widget,
+ GtkDeviceGroup *group,
+ GtkMultiDeviceEvent *event);
+static gboolean test_photo_album_widget_expose (GtkWidget *widget,
+ GdkEventExpose *event);
+
+G_DEFINE_TYPE (TestPhotoAlbumWidget, test_photo_album_widget, GTK_TYPE_DRAWING_AREA)
+
+
+static void
+test_photo_album_widget_class_init (TestPhotoAlbumWidgetClass *klass)
+{
+ GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->destroy = test_photo_album_widget_destroy;
+
+ widget_class->button_press_event = test_photo_album_widget_button_press;
+ widget_class->button_release_event = test_photo_album_widget_button_release;
+ widget_class->expose_event = test_photo_album_widget_expose;
+
+ g_type_class_add_private (klass, sizeof (TestPhotoAlbumWidgetPrivate));
+
+ quark_group_photo = g_quark_from_static_string ("group-photo");
+}
+
+static void
+test_photo_album_widget_init (TestPhotoAlbumWidget *album)
+{
+ TestPhotoAlbumWidgetPrivate *priv;
+ GtkWidget *widget;
+
+ priv = TEST_PHOTO_ALBUM_WIDGET_GET_PRIVATE (album);
+ widget = GTK_WIDGET (album);
+
+ priv->photos = g_ptr_array_new ();
+
+ gtk_widget_add_events (widget,
+ (GDK_POINTER_MOTION_MASK |
+ GDK_BUTTON_MOTION_MASK |
+ GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK));
+
+ gtk_widget_set_support_multidevice (widget, TRUE);
+
+ /* Multidevice events are not exposed through GtkWidgetClass */
+ g_signal_connect (album, "multidevice-event",
+ G_CALLBACK (test_photo_album_widget_multidevice_event), NULL);
+}
+
+static void
+calculate_rotated_point (gdouble angle,
+ gdouble zoom,
+ gdouble center_x,
+ gdouble center_y,
+ gdouble point_x,
+ gdouble point_y,
+ gdouble *ret_x,
+ gdouble *ret_y)
+{
+ gdouble distance, xd, yd, ang;
+
+ xd = center_x - point_x;
+ yd = center_y - point_y;
+
+ if (xd == 0 && yd == 0)
+ {
+ *ret_x = center_x;
+ *ret_y = center_y;
+ return;
+ }
+
+ distance = sqrt ((xd * xd) + (yd * yd));
+ distance *= zoom;
+
+ ang = atan2 (xd, yd);
+
+ /* Invert angle */
+ ang = (2 * G_PI) - ang;
+
+ /* Shift it 270° */
+ ang += 3 * (G_PI / 2);
+
+ /* And constraint it to 0°-360° */
+ ang = fmod (ang, 2 * G_PI);
+ ang += angle;
+
+ *ret_x = center_x + (distance * cos (ang));
+ *ret_y = center_y + (distance * sin (ang));
+}
+
+static void
+allocate_photo_region (TestPhoto *photo)
+{
+ GdkPoint points[4];
+ gint width, height, i;
+
+ width = gdk_pixbuf_get_width (photo->pixbuf);
+ height = gdk_pixbuf_get_height (photo->pixbuf);
+
+ /* Top/left */
+ points[0].x = photo->x - photo->center_x;
+ points[0].y = photo->y - photo->center_y;
+
+ /* Top/right */
+ points[1].x = photo->x - photo->center_x + width;
+ points[1].y = photo->y - photo->center_y;
+
+ /* Bottom/right */
+ points[2].x = photo->x - photo->center_x + width;
+ points[2].y = photo->y - photo->center_y + height;
+
+ /* Bottom/left */
+ points[3].x = photo->x - photo->center_x;
+ points[3].y = photo->y - photo->center_y + height;
+
+ for (i = 0; i < 4; i++)
+ {
+ gdouble ret_x, ret_y;
+
+ calculate_rotated_point (photo->angle,
+ photo->zoom,
+ photo->x,
+ photo->y,
+ (gdouble) points[i].x,
+ (gdouble) points[i].y,
+ &ret_x,
+ &ret_y);
+
+ points[i].x = (gint) ret_x;
+ points[i].y = (gint) ret_y;
+ }
+
+ if (photo->region)
+ gdk_region_destroy (photo->region);
+
+ photo->region = gdk_region_polygon (points, 4, GDK_WINDING_RULE);
+}
+
+static TestPhoto *
+test_photo_new (TestPhotoAlbumWidget *album,
+ GdkPixbuf *pixbuf)
+{
+ TestPhoto *photo;
+ static gdouble angle = 0;
+
+ photo = g_slice_new0 (TestPhoto);
+ photo->pixbuf = g_object_ref (pixbuf);
+ photo->group = gtk_widget_create_device_group (GTK_WIDGET (album));
+ g_object_set_qdata (G_OBJECT (photo->group), quark_group_photo, photo);
+
+ photo->center_x = 0;
+ photo->center_y = 0;
+ photo->x = 0;
+ photo->y = 0;
+ photo->angle = angle;
+ photo->zoom = 1.0;
+
+ angle += 0.1;
+
+ allocate_photo_region (photo);
+
+ return photo;
+}
+
+static void
+test_photo_free (TestPhoto *photo,
+ TestPhotoAlbumWidget *album)
+{
+ g_object_unref (photo->pixbuf);
+ gtk_widget_remove_device_group (GTK_WIDGET (album), photo->group);
+
+ g_slice_free (TestPhoto, photo);
+}
+
+static void
+test_photo_raise (TestPhoto *photo,
+ TestPhotoAlbumWidget *album)
+{
+ TestPhotoAlbumWidgetPrivate *priv;
+
+ priv = TEST_PHOTO_ALBUM_WIDGET_GET_PRIVATE (album);
+ g_ptr_array_remove (priv->photos, photo);
+ g_ptr_array_add (priv->photos, photo);
+}
+
+static void
+test_photo_album_widget_destroy (GtkObject *object)
+{
+ TestPhotoAlbumWidgetPrivate *priv;
+
+ priv = TEST_PHOTO_ALBUM_WIDGET_GET_PRIVATE (object);
+
+ if (priv->photos)
+ {
+ g_ptr_array_foreach (priv->photos, (GFunc) test_photo_free, object);
+ g_ptr_array_free (priv->photos, TRUE);
+ priv->photos = NULL;
+ }
+
+ GTK_OBJECT_CLASS (test_photo_album_widget_parent_class)->destroy (object);
+}
+
+static TestPhoto *
+find_photo_at_position (TestPhotoAlbumWidget *album,
+ gdouble x,
+ gdouble y)
+{
+ TestPhotoAlbumWidgetPrivate *priv;
+ TestPhoto *photo;
+ gint i;
+
+ priv = TEST_PHOTO_ALBUM_WIDGET_GET_PRIVATE (album);
+
+ for (i = priv->photos->len - 1; i >= 0; i--)
+ {
+ photo = g_ptr_array_index (priv->photos, i);
+
+ if (gdk_region_point_in (photo->region, (gint) x, (gint) y))
+ return photo;
+ }
+
+ return NULL;
+}
+
+static gboolean
+test_photo_album_widget_button_press (GtkWidget *widget,
+ GdkEventButton *event)
+{
+ TestPhoto *photo;
+
+ photo = find_photo_at_position (TEST_PHOTO_ALBUM_WIDGET (widget), event->x, event->y);
+
+ if (!photo)
+ return FALSE;
+
+ test_photo_raise (photo, TEST_PHOTO_ALBUM_WIDGET (widget));
+ gtk_device_group_add_device (photo->group, event->device);
+
+ return TRUE;
+}
+
+static gboolean
+test_photo_album_widget_button_release (GtkWidget *widget,
+ GdkEventButton *event)
+{
+ GtkDeviceGroup *group;
+
+ group = gtk_widget_get_group_for_device (widget, event->device);
+
+ if (group)
+ gtk_device_group_remove_device (group, event->device);
+
+ return TRUE;
+}
+
+static void
+test_photo_album_widget_multidevice_event (GtkWidget *widget,
+ GtkDeviceGroup *group,
+ GtkMultiDeviceEvent *event)
+{
+ TestPhotoAlbumWidgetPrivate *priv;
+ GdkRegion *region;
+ TestPhoto *photo;
+ gboolean new_center = FALSE;
+ gboolean new_position = FALSE;
+ gdouble event_x, event_y;
+
+ priv = TEST_PHOTO_ALBUM_WIDGET_GET_PRIVATE (widget);
+ photo = g_object_get_qdata (G_OBJECT (group), quark_group_photo);
+
+ region = gdk_region_copy (photo->region);
+
+ if (event->n_events == 1)
+ {
+ if (event->type == GTK_EVENT_DEVICE_REMOVED)
+ {
+ /* Device was just removed, unset zoom/angle info */
+ photo->base_zoom = 0;
+ photo->base_angle = 0;
+ photo->initial_angle = 0;
+ photo->initial_distance = 0;
+ new_center = TRUE;
+ }
+ else if (event->type == GTK_EVENT_DEVICE_ADDED)
+ new_center = TRUE;
+
+ event_x = event->events[0]->x;
+ event_y = event->events[0]->y;
+ new_position = TRUE;
+ }
+ else if (event->n_events == 2)
+ {
+ gdouble distance, angle;
+
+ gdk_events_get_center ((GdkEvent *) event->events[0],
+ (GdkEvent *) event->events[1],
+ &event_x, &event_y);
+
+ gdk_events_get_distance ((GdkEvent *) event->events[0],
+ (GdkEvent *) event->events[1],
+ &distance);
+
+ gdk_events_get_angle ((GdkEvent *) event->events[0],
+ (GdkEvent *) event->events[1],
+ &angle);
+
+ if (event->type == GTK_EVENT_DEVICE_ADDED)
+ {
+ photo->base_zoom = photo->zoom;
+ photo->base_angle = photo->angle;
+ photo->initial_angle = angle;
+ photo->initial_distance = distance;
+ new_center = TRUE;
+ }
+
+ photo->zoom = photo->base_zoom * (distance / photo->initial_distance);
+ photo->angle = photo->base_angle + (angle - photo->initial_angle);
+ new_position = TRUE;
+ }
+
+ if (new_center)
+ {
+ gdouble origin_x, origin_y;
+
+ origin_x = photo->x - photo->center_x;
+ origin_y = photo->y - photo->center_y;
+
+ calculate_rotated_point (- photo->angle,
+ 1 / photo->zoom,
+ photo->x - origin_x,
+ photo->y - origin_y,
+ event_x - origin_x,
+ event_y - origin_y,
+ &photo->center_x,
+ &photo->center_y);
+ }
+
+ if (new_position)
+ {
+ photo->x = event_x;
+ photo->y = event_y;
+ }
+
+ allocate_photo_region (photo);
+
+ gdk_region_union (region, photo->region);
+ gdk_region_shrink (region, -4, -4);
+
+ gdk_window_invalidate_region (widget->window, region, FALSE);
+}
+
+static gboolean
+test_photo_album_widget_expose (GtkWidget *widget,
+ GdkEventExpose *event)
+{
+ TestPhotoAlbumWidgetPrivate *priv;
+ cairo_t *cr;
+ gint i;
+
+ priv = TEST_PHOTO_ALBUM_WIDGET_GET_PRIVATE (widget);
+ cr = gdk_cairo_create (widget->window);
+
+ for (i = 0; i < priv->photos->len; i++)
+ {
+ TestPhoto *photo = g_ptr_array_index (priv->photos, i);
+ GdkRegion *region;
+ gint width, height;
+
+ region = gdk_region_copy (photo->region);
+ gdk_region_shrink (region, -4, -4);
+
+ gdk_region_intersect (region, event->region);
+
+ if (gdk_region_empty (region))
+ {
+ gdk_region_destroy (region);
+ continue;
+ }
+
+ width = gdk_pixbuf_get_width (photo->pixbuf);
+ height = gdk_pixbuf_get_height (photo->pixbuf);
+
+ cairo_save (cr);
+
+ gdk_cairo_region (cr, region);
+ cairo_clip (cr);
+
+ cairo_translate (cr, photo->x, photo->y);
+
+ cairo_scale (cr, photo->zoom, photo->zoom);
+ cairo_rotate (cr, photo->angle);
+ gdk_cairo_set_source_pixbuf (cr,
+ photo->pixbuf,
+ - photo->center_x,
+ - photo->center_y);
+
+ cairo_rectangle (cr,
+ - photo->center_x,
+ - photo->center_y,
+ width, height);
+ cairo_fill_preserve (cr);
+
+ cairo_set_source_rgb (cr, 0., 0., 0.);
+ cairo_stroke (cr);
+
+ cairo_restore (cr);
+
+ gdk_region_destroy (region);
+ }
+
+ cairo_destroy (cr);
+
+ return TRUE;
+}
+
+GtkWidget *
+test_photo_album_widget_new (void)
+{
+ return g_object_new (TEST_TYPE_PHOTO_ALBUM_WIDGET, NULL);
+}
+
+void
+test_photo_album_widget_add_image (TestPhotoAlbumWidget *album,
+ GdkPixbuf *pixbuf)
+{
+ TestPhotoAlbumWidgetPrivate *priv;
+ TestPhoto *photo;
+
+ g_return_if_fail (TEST_IS_PHOTO_ALBUM_WIDGET (album));
+ g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
+
+ priv = TEST_PHOTO_ALBUM_WIDGET_GET_PRIVATE (album);
+
+ photo = test_photo_new (album, pixbuf);
+ g_ptr_array_add (priv->photos, photo);
+
- if (GTK_WIDGET_REALIZED (album) &&
- GTK_WIDGET_DRAWABLE (album))
++ if (gtk_widget_get_realized (album) &&
++ gtk_widget_is_drawable (album))
+ gdk_window_invalidate_region (GTK_WIDGET (album)->window,
+ photo->region,
+ FALSE);
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]