Compare commits
181 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 39c8db124d | |||
| 1c11f6ed1a | |||
| 291ff93a6b | |||
| ccc4f0f133 | |||
| eecd228493 | |||
| f69179b562 | |||
| b79946956b | |||
| 1b5615df75 | |||
| adce361ec5 | |||
| 209e39ab8a | |||
| 3158630a68 | |||
| 2b02d97a93 | |||
| f194d499c3 | |||
| 3fd45e0267 | |||
| 2a537b5b8b | |||
| 89e420b390 | |||
| 426e8c8c97 | |||
| 78a8782b13 | |||
| da8de20928 | |||
| 2eaabf5ad3 | |||
| e299dfa462 | |||
| edd21e61f2 | |||
| 80a89c5245 | |||
| 739b6e1862 | |||
| 03a7331c5c | |||
| b078b9af86 | |||
| 29a42085c6 | |||
| e112cdacd4 | |||
| 828a97d773 | |||
| 820b0cafe0 | |||
| 04811d9483 | |||
| 8946cd70e1 | |||
| 78506bd604 | |||
| e486fb8118 | |||
| d6a559216f | |||
| 2cb739a2d5 | |||
| 398dc1cf27 | |||
| fc364e8a98 | |||
| ae867568b8 | |||
| 59d632c458 | |||
| 81e76746ff | |||
| c5f1dede79 | |||
| 8c45c8b53c | |||
| 515e211d0b | |||
| de3cfa6034 | |||
| 4e9f4fbc77 | |||
| f6079f6406 | |||
| 411321212b | |||
| 1ade42bf21 | |||
| c8b32350be | |||
| b2ec723262 | |||
| 79eeb78c46 | |||
| ed04b879c0 | |||
| 0101a735a3 | |||
| 7d1c1a8d20 | |||
| eaaee081b1 | |||
| 3cb4aa44b3 | |||
| 8a8c434737 | |||
| 0244dc8017 | |||
| fb6d4c2f3d | |||
| 8cbdd527f3 | |||
| b53f8ce0c9 | |||
| c5c46a125e | |||
| a28e1a22a6 | |||
| 710674720e | |||
| 5634eb226f | |||
| 4dd7de2e68 | |||
| 315d43e8a9 | |||
| 86d7c9d5b5 | |||
| fd9b7bbfac | |||
| fe48e077bd | |||
| dd45862a06 | |||
| ea5a56dacf | |||
| 694be447e3 | |||
| fbb38e95ac | |||
| ab3b41374a | |||
| 652f16dd98 | |||
| d30d56452c | |||
| 2e57819477 | |||
| d1c458f9e1 | |||
| 6b7eaf86ed | |||
| 78107b1a7d | |||
| f3177aff04 | |||
| 3ab16d7b54 | |||
| 9399275089 | |||
| 983a24cbcc | |||
| 81222237c5 | |||
| 4fa2f7a52e | |||
| f26123277f | |||
| 6eef2de682 | |||
| 21727b809c | |||
| 9ca355b460 | |||
| 106be0c5c9 | |||
| 628892bce8 | |||
| c88a969d13 | |||
| 72d11631db | |||
| 8ac04de2aa | |||
| 9d11da702b | |||
| 094fcd6fb7 | |||
| 374d48c37b | |||
| 45ecba2ea0 | |||
| 63e2a0ff0c | |||
| 58a9244518 | |||
| 66810c1e7f | |||
| 319bb2641b | |||
| 73bca14f74 | |||
| 08a7257349 | |||
| 9c43f671c1 | |||
| 3da26f5c2f | |||
| 560952d3c0 | |||
| 8062e471d1 | |||
| 1ec6329f18 | |||
| 512fee6363 | |||
| 2d7c23730c | |||
| 78ad6f8b71 | |||
| e3aa565bbb | |||
| 5f28b7c114 | |||
| 7dff6800e5 | |||
| f89d5c8280 | |||
| e2c15e2791 | |||
| 2661403f88 | |||
| 5a3442bf9c | |||
| 4942b6f5e4 | |||
| 351c1ab149 | |||
| 6fe0fbd4e2 | |||
| d0d21a4f00 | |||
| e8dcfad441 | |||
| 1067627131 | |||
| 71d95cecd7 | |||
| c549047474 | |||
| c069267c42 | |||
| bdbd47818f | |||
| d1091c8bda | |||
| 357a2bb926 | |||
| 13ad089bdf | |||
| 1c90f6b6c6 | |||
| bb2ebce5af | |||
| e5269ebbcd | |||
| 4a7d830780 | |||
| 8f55b2775a | |||
| 3941a80798 | |||
| c1218f964a | |||
| 844e793246 | |||
| b936666b52 | |||
| 0ac56e9dcc | |||
| 746b9d7c41 | |||
| 3e78324501 | |||
| 8d0e88bac7 | |||
| 144a5687c9 | |||
| f92a092bac | |||
| 9d3a49bbb6 | |||
| f061990bd5 | |||
| ce74104198 | |||
| 488baeef98 | |||
| 84d28bac66 | |||
| 114267c867 | |||
| 7ce11d1521 | |||
| 68c5c24289 | |||
| 4e41a6659f | |||
| 2cf924117a | |||
| ae81246512 | |||
| 9613cf68bd | |||
| fcfbafc9fe | |||
| c2681d585e | |||
| 8ded24fbf7 | |||
| 44da798055 | |||
| 7c51d67e7c | |||
| 8a39d2269e | |||
| 1a0a8e112e | |||
| c5ef4e660b | |||
| 0ea892069b | |||
| c195421a4e | |||
| eaddf70a43 | |||
| 96c19108fc | |||
| 33e928e472 | |||
| d2c66e5afd | |||
| bef037f5d2 | |||
| b5773b89cf | |||
| a4c80bd9cb | |||
| d2267824b3 | |||
| fb76a0a000 |
@@ -1,3 +1,85 @@
|
||||
Overview of Changes in GTK+ 3.5.12
|
||||
==================================
|
||||
|
||||
* GtkApplication:
|
||||
- Add gtk_application_get_active_window to get the active window
|
||||
- Add gtk_widget_insert_action_group to allow more flexibility
|
||||
when associating widgets with actions
|
||||
|
||||
* GtkMenuButton:
|
||||
- The gtk_menu_button_set_menu function is getting renamed
|
||||
to gtk_menu_button_set_popup. The old name is still available
|
||||
for now, but will be removed before 3.6
|
||||
|
||||
* GtkToolbar:
|
||||
- use CSS properties instead of style properties for padding
|
||||
|
||||
* Input method support:
|
||||
- GtkEntry and GtkTextView now have input-purpose and input-hints
|
||||
properties that let applications provide useful hints to
|
||||
input methods, like 'this entry is for a phone nr'.
|
||||
|
||||
* Bugs:
|
||||
373279 Toggling a GtkToggleButton emits "clicked", not "toggled"
|
||||
651244 Add a "purpose" tag for GtkEntries
|
||||
673478 Chain up notify implementations
|
||||
681577 Missing mnemonic in "Find applications online"
|
||||
681591 Masked string for password fields is not exposed to accessibility
|
||||
681613 icon view doesn't emit selection changed when the model changes
|
||||
682193 404 in GTK+ docs for duplicated "stable" URL suffix to ATK link
|
||||
682235 gtkmenubutton: repurpose set_menu for GMenuModel
|
||||
|
||||
* Translation updates:
|
||||
Assamese
|
||||
Esperanto
|
||||
Galician
|
||||
Lithuanian
|
||||
Marathi
|
||||
Portuguese
|
||||
Serbian
|
||||
Spanish
|
||||
Traditional Chinese
|
||||
|
||||
|
||||
Overview of Changes in GTK+ 3.5.10
|
||||
==================================
|
||||
|
||||
* Wayland:
|
||||
- Add keyboard handling
|
||||
- Improve clipboard handling
|
||||
- Add default settings implementation
|
||||
|
||||
* GDK thread support has been deprecated
|
||||
|
||||
* Bugs fixed:
|
||||
679910 GtkTreeModelFilter: Fix _iter_previous() when iter...
|
||||
679978 Optimize gtk_widget_path_copy() by preallocating "...
|
||||
680754 deprecate gdk thread functions
|
||||
680803 menubutton: Clear references in dispose, not finalize
|
||||
680822 Document return value of GtkWidget::draw
|
||||
680901 GTK+: The chinese translations of "even sheet" and...
|
||||
680949 GtkColorButton documentation seems self-contradictory
|
||||
680988 GtkMenuButton down direction positioning suboptimal
|
||||
681005 [IconView] wrong transfer annotation for get_toolt...
|
||||
681006 Escape should cancel DnD operation
|
||||
681064 container: restyle queue leaks
|
||||
|
||||
* Updated translations
|
||||
Galician
|
||||
German
|
||||
Greek
|
||||
Gujarati
|
||||
Japanese
|
||||
Kazakh
|
||||
Norwegian bokmål
|
||||
Persian
|
||||
Serbian
|
||||
Slovenian
|
||||
Spanish
|
||||
Telugu
|
||||
Traditional Chinese
|
||||
|
||||
|
||||
Overview of Changes in GTK+ 3.5.8
|
||||
=================================
|
||||
|
||||
|
||||
@@ -26,16 +26,17 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
@@ -62,11 +63,10 @@
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</LinkIncremental>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
@@ -35,6 +36,7 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
@@ -35,6 +36,7 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
@@ -62,9 +64,9 @@
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</LinkIncremental>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</LinkIncremental>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
@@ -81,11 +83,11 @@
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>imm32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)$(GtkDllPrefix)$(ProjectName)-win32$(GtkDllSuffix).dll</OutputFile>
|
||||
<OutputFile>$(OutDir)$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll</OutputFile>
|
||||
<ModuleDefinitionFile>$(IntDir)gdk.def</ModuleDefinitionFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<ImportLibrary>$(TargetDir)$(ProjectName)-win32-$(GtkApiVersion).lib</ImportLibrary>
|
||||
<ImportLibrary>$(TargetDir)$(ProjectName)-$(GtkApiVersion).lib</ImportLibrary>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
@@ -101,13 +103,13 @@
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>imm32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)$(GtkDllPrefix)$(ProjectName)-win32$(GtkDllSuffix).dll</OutputFile>
|
||||
<OutputFile>$(OutDir)$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll</OutputFile>
|
||||
<ModuleDefinitionFile>$(IntDir)gdk.def</ModuleDefinitionFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<ImportLibrary>$(TargetDir)$(ProjectName)-win32-$(GtkApiVersion).lib</ImportLibrary>
|
||||
<ImportLibrary>$(TargetDir)$(ProjectName)-$(GtkApiVersion).lib</ImportLibrary>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
@@ -126,11 +128,11 @@
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>imm32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)$(GtkDllPrefix)$(ProjectName)-win32$(GtkDllSuffix).dll</OutputFile>
|
||||
<OutputFile>$(OutDir)$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll</OutputFile>
|
||||
<ModuleDefinitionFile>$(IntDir)gdk.def</ModuleDefinitionFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<ImportLibrary>$(TargetDir)$(ProjectName)-win32-$(GtkApiVersion).lib</ImportLibrary>
|
||||
<ImportLibrary>$(TargetDir)$(ProjectName)-$(GtkApiVersion).lib</ImportLibrary>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
@@ -146,13 +148,13 @@
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>imm32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)$(GtkDllPrefix)$(ProjectName)-win32$(GtkDllSuffix).dll</OutputFile>
|
||||
<OutputFile>$(OutDir)$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll</OutputFile>
|
||||
<ModuleDefinitionFile>$(IntDir)gdk.def</ModuleDefinitionFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<ImportLibrary>$(TargetDir)$(ProjectName)-win32-$(GtkApiVersion).lib</ImportLibrary>
|
||||
<ImportLibrary>$(TargetDir)$(ProjectName)-$(GtkApiVersion).lib</ImportLibrary>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
@@ -591,8 +591,6 @@ copy ..\..\..\gdk\gdkconfig.h $(CopyDir)\include\gtk-3.0\gdk
|
||||
|
||||
copy $(Configuration)\$(Platform)\bin\*-$(GtkApiVersion).lib $(CopyDir)\lib
|
||||
|
||||
copy $(Configuration)\$(Platform)\bin\gailutil.lib $(CopyDir)\lib
|
||||
|
||||
|
||||
mkdir $(CopyDir)\share\glib-2.0\schemas
|
||||
|
||||
|
||||
@@ -12,10 +12,12 @@
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
@@ -62,9 +64,9 @@
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</LinkIncremental>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</LinkIncremental>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
@@ -81,11 +83,11 @@
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>atk-1.0.lib;pangowin32-1.0.lib;imm32.lib;winspool.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)$(GtkDllPrefix)$(ProjectName)-win32$(GtkDllSuffix).dll</OutputFile>
|
||||
<OutputFile>$(OutDir)$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll</OutputFile>
|
||||
<ModuleDefinitionFile>$(IntDir)gtk.def</ModuleDefinitionFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<ImportLibrary>$(TargetDir)$(ProjectName)-win32-$(GtkApiVersion).lib</ImportLibrary>
|
||||
<ImportLibrary>$(TargetDir)$(ProjectName)-$(GtkApiVersion).lib</ImportLibrary>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
@@ -101,13 +103,13 @@
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>atk-1.0.lib;pangowin32-1.0.lib;imm32.lib;winspool.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)$(GtkDllPrefix)$(ProjectName)-win32$(GtkDllSuffix).dll</OutputFile>
|
||||
<OutputFile>$(OutDir)$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll</OutputFile>
|
||||
<ModuleDefinitionFile>$(IntDir)gtk.def</ModuleDefinitionFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<ImportLibrary>$(TargetDir)$(ProjectName)-win32-$(GtkApiVersion).lib</ImportLibrary>
|
||||
<ImportLibrary>$(TargetDir)$(ProjectName)-$(GtkApiVersion).lib</ImportLibrary>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
@@ -126,11 +128,11 @@
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>atk-1.0.lib;pangowin32-1.0.lib;imm32.lib;winspool.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)$(GtkDllPrefix)$(ProjectName)-win32$(GtkDllSuffix).dll</OutputFile>
|
||||
<OutputFile>$(OutDir)$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll</OutputFile>
|
||||
<ModuleDefinitionFile>$(IntDir)gtk.def</ModuleDefinitionFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<ImportLibrary>$(TargetDir)$(ProjectName)-win32-$(GtkApiVersion).lib</ImportLibrary>
|
||||
<ImportLibrary>$(TargetDir)$(ProjectName)-$(GtkApiVersion).lib</ImportLibrary>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
@@ -146,13 +148,13 @@
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>atk-1.0.lib;pangowin32-1.0.lib;imm32.lib;winspool.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)$(GtkDllPrefix)$(ProjectName)-win32$(GtkDllSuffix).dll</OutputFile>
|
||||
<OutputFile>$(OutDir)$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll</OutputFile>
|
||||
<ModuleDefinitionFile>$(IntDir)gtk.def</ModuleDefinitionFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<ImportLibrary>$(TargetDir)$(ProjectName)-win32-$(GtkApiVersion).lib</ImportLibrary>
|
||||
<ImportLibrary>$(TargetDir)$(ProjectName)-$(GtkApiVersion).lib</ImportLibrary>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
@@ -26,16 +26,17 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
Name="Debug|Win32"
|
||||
InheritedPropertySheets=".\gtk+.vsprops"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="1"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
@@ -42,7 +42,7 @@
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="2"
|
||||
LinkIncremental="1"
|
||||
AdditionalDependencies="atk-1.0.lib"
|
||||
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll"
|
||||
GenerateDebugInformation="true"
|
||||
@@ -77,7 +77,7 @@
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="atk-1.0.lib"
|
||||
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll"
|
||||
LinkIncremental="2"
|
||||
LinkIncremental="1"
|
||||
ModuleDefinitionFile="..\..\..\libgail-util\gailutil.def"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
@@ -89,7 +89,7 @@
|
||||
Name="Release|Win32"
|
||||
InheritedPropertySheets=".\gtk+.vsprops"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="1"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
@@ -126,6 +126,7 @@
|
||||
InheritedPropertySheets=".\gtk+.vsprops"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
@@ -143,7 +144,7 @@
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="atk-1.0.lib"
|
||||
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll"
|
||||
LinkIncremental="2"
|
||||
LinkIncremental="1"
|
||||
ModuleDefinitionFile="..\..\..\libgail-util\gailutil.def"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
InheritedPropertySheets=".\gtk+.vsprops"
|
||||
ConfigurationType="4"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
@@ -87,6 +88,7 @@
|
||||
InheritedPropertySheets=".\gtk+.vsprops"
|
||||
ConfigurationType="4"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
|
||||
@@ -43,12 +43,12 @@
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="imm32.lib"
|
||||
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)-win32$(GtkDllSuffix).dll"
|
||||
LinkIncremental="2"
|
||||
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll"
|
||||
LinkIncremental="1"
|
||||
ModuleDefinitionFile="$(IntDir)\gdk.def"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
ImportLibrary="$(TargetDir)$(ProjectName)-win32-$(GtkApiVersion).lib"
|
||||
ImportLibrary="$(TargetDir)$(ProjectName)-$(GtkApiVersion).lib"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
</Configuration>
|
||||
@@ -57,6 +57,7 @@
|
||||
InheritedPropertySheets=".\gtk+.vsprops"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
@@ -73,14 +74,14 @@
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="imm32.lib"
|
||||
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)-win32$(GtkDllSuffix).dll"
|
||||
LinkIncremental="2"
|
||||
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll"
|
||||
LinkIncremental="1"
|
||||
ModuleDefinitionFile="$(IntDir)\gdk.def"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
ImportLibrary="$(TargetDir)$(ProjectName)-win32-$(GtkApiVersion).lib"
|
||||
ImportLibrary="$(TargetDir)$(ProjectName)-$(GtkApiVersion).lib"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
</Configuration>
|
||||
@@ -108,12 +109,12 @@
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="imm32.lib"
|
||||
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)-win32$(GtkDllSuffix).dll"
|
||||
LinkIncremental="2"
|
||||
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll"
|
||||
LinkIncremental="1"
|
||||
ModuleDefinitionFile="$(IntDir)\gdk.def"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
ImportLibrary="$(TargetDir)$(ProjectName)-win32-$(GtkApiVersion).lib"
|
||||
ImportLibrary="$(TargetDir)$(ProjectName)-$(GtkApiVersion).lib"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
</Configuration>
|
||||
@@ -122,6 +123,7 @@
|
||||
InheritedPropertySheets=".\gtk+.vsprops"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
@@ -138,14 +140,14 @@
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="imm32.lib"
|
||||
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)-win32$(GtkDllSuffix).dll"
|
||||
LinkIncremental="2"
|
||||
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll"
|
||||
LinkIncremental="1"
|
||||
ModuleDefinitionFile="$(IntDir)\gdk.def"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
ImportLibrary="$(TargetDir)$(ProjectName)-win32-$(GtkApiVersion).lib"
|
||||
ImportLibrary="$(TargetDir)$(ProjectName)-$(GtkApiVersion).lib"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
</Configuration>
|
||||
|
||||
@@ -361,7 +361,6 @@ copy ..\..\..\libgail-util\gailtextutil.h $(CopyDir)\include\gail-$(GtkApiVersio
|
||||
copy ..\..\..\gdk\gdkconfig.h $(CopyDir)\include\gtk-3.0\gdk

|
||||
|
||||
copy $(ConfigurationName)\$(PlatformName)\bin\*-$(GtkApiVersion).lib $(CopyDir)\lib

|
||||
copy $(ConfigurationName)\$(PlatformName)\bin\gailutil.lib $(CopyDir)\lib

|
||||
|
||||
mkdir $(CopyDir)\share\glib-2.0\schemas

|
||||
copy ..\..\..\gtk\org.gtk.Settings.FileChooser.gschema.xml $(CopyDir)\share\glib-2.0\schemas

|
||||
|
||||
@@ -43,12 +43,12 @@
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="atk-1.0.lib pangowin32-1.0.lib imm32.lib winspool.lib comctl32.lib"
|
||||
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)-win32$(GtkDllSuffix).dll"
|
||||
LinkIncremental="2"
|
||||
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll"
|
||||
LinkIncremental="1"
|
||||
ModuleDefinitionFile="$(IntDir)\gtk.def"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
ImportLibrary="$(TargetDir)$(ProjectName)-win32-$(GtkApiVersion).lib"
|
||||
ImportLibrary="$(TargetDir)$(ProjectName)-$(GtkApiVersion).lib"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
</Configuration>
|
||||
@@ -57,6 +57,7 @@
|
||||
InheritedPropertySheets=".\gtk+.vsprops"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
@@ -73,14 +74,14 @@
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="atk-1.0.lib pangowin32-1.0.lib imm32.lib winspool.lib comctl32.lib"
|
||||
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)-win32$(GtkDllSuffix).dll"
|
||||
LinkIncremental="2"
|
||||
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll"
|
||||
LinkIncremental="1"
|
||||
ModuleDefinitionFile="$(IntDir)\gtk.def"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
ImportLibrary="$(TargetDir)$(ProjectName)-win32-$(GtkApiVersion).lib"
|
||||
ImportLibrary="$(TargetDir)$(ProjectName)-$(GtkApiVersion).lib"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
</Configuration>
|
||||
@@ -108,12 +109,12 @@
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="atk-1.0.lib pangowin32-1.0.lib imm32.lib winspool.lib comctl32.lib"
|
||||
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)-win32$(GtkDllSuffix).dll"
|
||||
LinkIncremental="2"
|
||||
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll"
|
||||
LinkIncremental="1"
|
||||
ModuleDefinitionFile="$(IntDir)\gtk.def"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
ImportLibrary="$(TargetDir)$(ProjectName)-win32-$(GtkApiVersion).lib"
|
||||
ImportLibrary="$(TargetDir)$(ProjectName)-$(GtkApiVersion).lib"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
</Configuration>
|
||||
@@ -122,6 +123,7 @@
|
||||
InheritedPropertySheets=".\gtk+.vsprops"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
@@ -138,14 +140,14 @@
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="atk-1.0.lib pangowin32-1.0.lib imm32.lib winspool.lib comctl32.lib"
|
||||
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)-win32$(GtkDllSuffix).dll"
|
||||
LinkIncremental="2"
|
||||
OutputFile="$(OutDir)\$(GtkDllPrefix)$(ProjectName)$(GtkDllSuffix).dll"
|
||||
LinkIncremental="1"
|
||||
ModuleDefinitionFile="$(IntDir)\gtk.def"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
ImportLibrary="$(TargetDir)$(ProjectName)-win32-$(GtkApiVersion).lib"
|
||||
ImportLibrary="$(TargetDir)$(ProjectName)-$(GtkApiVersion).lib"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
</Configuration>
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies=""
|
||||
LinkIncremental="2"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
RandomizedBaseAddress="1"
|
||||
@@ -77,7 +77,7 @@
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies=""
|
||||
LinkIncremental="2"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
RandomizedBaseAddress="1"
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
Name="Debug|Win32"
|
||||
InheritedPropertySheets=".\gtk+.vsprops"
|
||||
ConfigurationType="4"
|
||||
CharacterSet="1"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
@@ -67,7 +67,7 @@
|
||||
Name="Release|Win32"
|
||||
InheritedPropertySheets=".\gtk+.vsprops"
|
||||
ConfigurationType="4"
|
||||
CharacterSet="1"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
@@ -91,6 +91,7 @@
|
||||
InheritedPropertySheets=".\gtk+.vsprops"
|
||||
ConfigurationType="4"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
m4_define([gtk_major_version], [3])
|
||||
m4_define([gtk_minor_version], [5])
|
||||
m4_define([gtk_micro_version], [8])
|
||||
m4_define([gtk_micro_version], [13])
|
||||
m4_define([gtk_interface_age], [0])
|
||||
m4_define([gtk_binary_age],
|
||||
[m4_eval(100 * gtk_minor_version + gtk_micro_version)])
|
||||
@@ -987,11 +987,13 @@ if test "x$enable_x11_backend" = xyes; then
|
||||
|
||||
AC_MSG_CHECKING([if <X11/extensions/XIproto.h> is needed for xReply])
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <X11/Xlibint.h>]],
|
||||
[[xReply *rep;]])],
|
||||
[[xReply *rep = NULL;
|
||||
rep = rep;]])],
|
||||
[AC_MSG_RESULT([no])],
|
||||
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <X11/extensions/XIproto.h>
|
||||
#include <X11/Xlibint.h>]],
|
||||
[[xReply *rep;]])],
|
||||
[[xReply *rep = NULL;
|
||||
rep = rep;]])],
|
||||
[AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([NEED_XIPROTO_H_FOR_XREPLY], [1],
|
||||
[Define if <X11/extensions/XIproto.h> needed for xReply])],
|
||||
@@ -1603,33 +1605,53 @@ AM_CONDITIONAL(HAVE_COLORD, test "x$have_colord" = "xyes")
|
||||
|
||||
GTK_DOC_CHECK([1.11],[--flavour no-tmpl])
|
||||
|
||||
AC_CHECK_PROG(DB2HTML, db2html, true, false)
|
||||
AM_CONDITIONAL(HAVE_DOCBOOK, $DB2HTML)
|
||||
|
||||
AC_ARG_ENABLE(man,
|
||||
[AS_HELP_STRING([--enable-man],
|
||||
[regenerate man pages from Docbook [default=no]])],
|
||||
[enable_man=yes],
|
||||
[enable_man=no])
|
||||
[generate man pages [default=auto]])],,
|
||||
enable_man=maybe)
|
||||
|
||||
if test "${enable_man}" != no; then
|
||||
dnl
|
||||
dnl Check for xsltproc
|
||||
dnl
|
||||
if test "$enable_man" != no; then
|
||||
AC_PATH_PROG([XSLTPROC], [xsltproc])
|
||||
if test -z "$XSLTPROC"; then
|
||||
if test "$enable_man" = yes ; then
|
||||
AC_MSG_ERROR([xsltproc is required for --enable-man])
|
||||
fi
|
||||
enable_man=no
|
||||
fi
|
||||
|
||||
dnl check for DocBook DTD and stylesheets in the local catalog.
|
||||
JH_CHECK_XML_CATALOG([-//OASIS//DTD DocBook XML V4.1.2//EN],
|
||||
[DocBook XML DTD V4.1.2],,enable_man=no)
|
||||
JH_CHECK_XML_CATALOG([http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl],
|
||||
[DocBook XSL Stylesheets],,enable_man=no)
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(ENABLE_MAN, test x$enable_man != xno)
|
||||
if test "$enable_man" != no; then
|
||||
dnl check for DocBook DTD in the local catalog
|
||||
JH_CHECK_XML_CATALOG([-//OASIS//DTD DocBook XML V4.1.2//EN],
|
||||
[DocBook XML DTD V4.1.2], [have_docbook_dtd=yes], [have_docbook_dtd=no])
|
||||
if test "$have_docbook_dtd" != yes; then
|
||||
if test "$enable_man" = yes ; then
|
||||
AC_MSG_ERROR([DocBook DTD is required for --enable-man])
|
||||
fi
|
||||
enable_man=no
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "$enable_man" != no; then
|
||||
dnl check for DocBook XSL stylesheets in the local catalog
|
||||
JH_CHECK_XML_CATALOG([http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl],
|
||||
[DocBook XSL Stylesheets], [have_docbook_style=yes],[have_docbook_style=no])
|
||||
if test "$have_docbook_dtd" != yes; then
|
||||
if test "$enable_man" = yes ; then
|
||||
AC_MSG_ERROR([DocBook XSL Stylesheets are required for --enable-man])
|
||||
fi
|
||||
enable_man=no
|
||||
fi
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(ENABLE_MAN, test "$enable_man" != no)
|
||||
|
||||
AC_MSG_CHECKING([whether to generate man pages])
|
||||
if test "$enable_man" != no; then
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
|
||||
##################################################
|
||||
# Output commands
|
||||
|
||||
@@ -175,9 +175,7 @@ timeout (gpointer data)
|
||||
: MAX (127, fabs (255 * cos (f * 2.0 * G_PI)))));
|
||||
}
|
||||
|
||||
GDK_THREADS_ENTER ();
|
||||
gtk_widget_queue_draw (da);
|
||||
GDK_THREADS_LEAVE ();
|
||||
|
||||
frame_num++;
|
||||
return G_SOURCE_CONTINUE;
|
||||
|
||||
@@ -1136,6 +1136,33 @@ Suspendisse feugiat quam quis dolor accumsan cursus. </property>
|
||||
<property name="position">8</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLevelBar" id="levelbar1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="value">0.6</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">9</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLevelBar" id="levelbar2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="min-value">0</property>
|
||||
<property name="max-value">5</property>
|
||||
<property name="value">2</property>
|
||||
<property name="mode">1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">10</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
|
||||
@@ -309,6 +309,7 @@ HTML_IMAGES = \
|
||||
$(srcdir)/images/icon-view.png \
|
||||
$(srcdir)/images/image.png \
|
||||
$(srcdir)/images/label.png \
|
||||
$(srcdir)/images/levelbar.png \
|
||||
$(srcdir)/images/link-button.png \
|
||||
$(srcdir)/images/list-and-tree.png \
|
||||
$(srcdir)/images/lock-button.png \
|
||||
@@ -381,7 +382,19 @@ HTML_IMAGES = \
|
||||
$(srcdir)/images/numerableicon2.png \
|
||||
$(srcdir)/images/bloatpad-osx.png \
|
||||
$(srcdir)/images/bloatpad-gnome.png \
|
||||
$(srcdir)/images/bloatpad-xfce.png
|
||||
$(srcdir)/images/bloatpad-xfce.png \
|
||||
$(srcdir)/images/down-center.png \
|
||||
$(srcdir)/images/down-end.png \
|
||||
$(srcdir)/images/down-start.png \
|
||||
$(srcdir)/images/left-center.png \
|
||||
$(srcdir)/images/left-end.png \
|
||||
$(srcdir)/images/left-start.png \
|
||||
$(srcdir)/images/right-center.png \
|
||||
$(srcdir)/images/right-end.png \
|
||||
$(srcdir)/images/right-start.png \
|
||||
$(srcdir)/images/up-center.png \
|
||||
$(srcdir)/images/up-end.png \
|
||||
$(srcdir)/images/up-start.png
|
||||
|
||||
# Extra options to supply to gtkdoc-fixref
|
||||
FIXXREF_OPTIONS=--extra-dir=../gdk/html \
|
||||
@@ -406,8 +419,16 @@ man_MANS = \
|
||||
|
||||
if ENABLE_MAN
|
||||
|
||||
XSLTPROC_FLAGS = \
|
||||
--nonet \
|
||||
--stringparam man.output.quietly 1 \
|
||||
--stringparam funcsynopsis.style ansi \
|
||||
--stringparam man.th.extra1.suppress 1 \
|
||||
--stringparam man.authors.section.enabled 0 \
|
||||
--stringparam man.copyright.section.enabled 0
|
||||
|
||||
.xml.1:
|
||||
@XSLTPROC@ -nonet http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $<
|
||||
$(AM_V_GEN) $(XSLTPROC) $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $<
|
||||
|
||||
dist-local-check-mans-enabled:
|
||||
if grep "Man generation disabled" $(man_MANS) >/dev/null; then $(RM) $(man_MANS); fi
|
||||
|
||||
@@ -63,6 +63,22 @@ to use. APIs that were deprecated before or introduced after
|
||||
this range will trigger compiler warnings.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Here is how you would compile hello.c if you want to allow it
|
||||
to use symbols that were not deprecated in 3.2:
|
||||
<programlisting>
|
||||
$ cc -DGDK_VERSION_MIN_REQIRED=GDK_VERSION_3_2 `pkg-config --cflags --libs gtk+-3.0` hello.c -o hello
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
And here is how you would compile hello.c if you don't want
|
||||
it to use any symbols that were introduced after 3.4:
|
||||
<programlisting>
|
||||
$ cc -DGDK_VERSION_MAX_ALLOWED=GDK_VERSION_3_4 `pkg-config --cflags --libs gtk+-3.0` hello.c -o hello
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The older deprecation mechanism of hiding deprecated interfaces
|
||||
entirely from the compiler by using the preprocessor symbol
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
<refentryinfo>
|
||||
<title>gtk-launch</title>
|
||||
<productname>gtk+</productname>
|
||||
<productname>GTK+</productname>
|
||||
<authorgroup>
|
||||
<author>
|
||||
<contrib>Developer</contrib>
|
||||
@@ -48,8 +48,9 @@ the application to launch. The name should match application desktop file name,
|
||||
as residing in /usr/share/application, with or without the '.desktop' suffix.
|
||||
</para>
|
||||
<para>
|
||||
If called with more than one argument, the rest of them besides the application name
|
||||
are considered URI locations and are passed as arguments to the launched application.
|
||||
If called with more than one argument, the rest of them besides the application
|
||||
name are considered URI locations and are passed as arguments to the launched
|
||||
application.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
@@ -63,10 +64,4 @@ are considered URI locations and are passed as arguments to the launched applica
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1><title>Bugs</title>
|
||||
<para>
|
||||
None known yet.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
</refentry>
|
||||
|
||||
@@ -4,6 +4,18 @@
|
||||
]>
|
||||
<refentry id="gtk-query-immodules-3.0">
|
||||
|
||||
<refentryinfo>
|
||||
<title>gtk-query-immodules-3.0</title>
|
||||
<productname>GTK+</productname>
|
||||
<authorgroup>
|
||||
<author>
|
||||
<contrib>Developer</contrib>
|
||||
<firstname>Matthias</firstname>
|
||||
<surname>Clasen</surname>
|
||||
</author>
|
||||
</authorgroup>
|
||||
</refentryinfo>
|
||||
|
||||
<refmeta>
|
||||
<refentrytitle>gtk-query-immodules-3.0</refentrytitle>
|
||||
<manvolnum>1</manvolnum>
|
||||
@@ -19,7 +31,7 @@
|
||||
<cmdsynopsis>
|
||||
<command>gtk-query-immodules-3.0</command>
|
||||
<arg choice="opt">--update-cache</arg>
|
||||
<arg choice="opt" rep="repeat">module</arg>
|
||||
<arg choice="opt" rep="repeat">MODULE</arg>
|
||||
</cmdsynopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
@@ -37,11 +49,13 @@ module path.
|
||||
If called with arguments, it looks for the specified modules. The arguments
|
||||
may be absolute or relative paths.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Normally, the output of <command>gtk-query-immodules-3.0</command> is written
|
||||
to <filename><replaceable>libdir</replaceable>/gtk-3.0/3.0.0/immodules.cache</filename>, where GTK+ looks for it by default. If it is written to some other
|
||||
location, the environment variable <link linkend="gtk-im-module-file"><envar>GTK_IM_MODULE_FILE</envar></link>
|
||||
can be set to point GTK+ at the file.
|
||||
to <filename><replaceable>libdir</replaceable>/gtk-3.0/3.0.0/immodules.cache</filename>,
|
||||
where GTK+ looks for it by default. If it is written to some other location,
|
||||
the <envar>GTK_IM_MODULE_FILE</envar> environment variable can be set to point
|
||||
GTK+ at the file.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
@@ -55,19 +69,28 @@ can be set to point GTK+ at the file.
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1><title>Environment</title>
|
||||
<para>
|
||||
The environment variable <link linkend="gtk-path"><envar>GTK_PATH</envar></link>
|
||||
can be used to prepend directories to the input method module path.
|
||||
</para>
|
||||
<refsect1><title>Files</title>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><filename><replaceable>libdir</replaceable>/gtk-3.0/3.0.0/immodules.cache</filename></term>
|
||||
<listitem><para>The default im cache file used by GTK+ applications</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
</refsect1>
|
||||
|
||||
<refsect1><title>Bugs</title>
|
||||
<para>
|
||||
None known yet.
|
||||
</para>
|
||||
<refsect1><title>Environment</title>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><link linkend="gtk-path"><envar>GTK_PATH</envar></link></term>
|
||||
<listitem><para>Prepends directories to the input method module path</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><link linkend="gtk-im-module-file"><envar>GTK_IM_MODULE_FILE</envar></link></term>
|
||||
<listitem><para>Specifies an alternative im module cache for GTK+
|
||||
applications</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
</refentry>
|
||||
|
||||
|
||||
|
||||
@@ -4,6 +4,18 @@
|
||||
]>
|
||||
<refentry id="gtk-update-icon-cache">
|
||||
|
||||
<refentryinfo>
|
||||
<title>gtk-update-icon-cache</title>
|
||||
<productname>GTK+</productname>
|
||||
<authorgroup>
|
||||
<author>
|
||||
<contrib>Developer</contrib>
|
||||
<firstname>Matthias</firstname>
|
||||
<surname>Clasen</surname>
|
||||
</author>
|
||||
</authorgroup>
|
||||
</refentryinfo>
|
||||
|
||||
<refmeta>
|
||||
<refentrytitle>gtk-update-icon-cache</refentrytitle>
|
||||
<manvolnum>1</manvolnum>
|
||||
@@ -99,10 +111,4 @@
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1><title>Bugs</title>
|
||||
<para>
|
||||
None known yet.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
</refentry>
|
||||
|
||||
@@ -1081,6 +1081,12 @@ gtk_entry_get_icon_tooltip_markup
|
||||
gtk_entry_set_icon_drag_source
|
||||
gtk_entry_get_current_icon_drag_source
|
||||
gtk_entry_get_icon_area
|
||||
GtkInputPurpose
|
||||
gtk_entry_set_input_purpose
|
||||
gtk_entry_get_input_purpose
|
||||
GtkInputHints
|
||||
gtk_entry_set_input_hints
|
||||
gtk_entry_get_input_hints
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GTK_ENTRY
|
||||
@@ -2130,8 +2136,8 @@ gtk_menu_bar_get_type
|
||||
<TITLE>GtkMenuButton</TITLE>
|
||||
GtkMenuButton
|
||||
gtk_menu_button_new
|
||||
gtk_menu_button_set_menu
|
||||
gtk_menu_button_get_menu
|
||||
gtk_menu_button_set_popup
|
||||
gtk_menu_button_get_popup
|
||||
gtk_menu_button_set_menu_model
|
||||
gtk_menu_button_get_menu_model
|
||||
gtk_menu_button_set_direction
|
||||
@@ -3672,6 +3678,10 @@ gtk_text_view_get_accepts_tab
|
||||
gtk_text_view_get_default_attributes
|
||||
gtk_text_view_im_context_filter_keypress
|
||||
gtk_text_view_reset_im_context
|
||||
gtk_text_view_set_input_purpose
|
||||
gtk_text_view_get_input_purpose
|
||||
gtk_text_view_set_input_hints
|
||||
gtk_text_view_get_input_hints
|
||||
GTK_TEXT_VIEW_PRIORITY_VALIDATE
|
||||
<SUBSECTION Standard>
|
||||
GTK_TEXT_VIEW
|
||||
@@ -5291,6 +5301,7 @@ gtk_widget_get_mapped
|
||||
gtk_widget_get_requisition
|
||||
gtk_widget_device_is_shadowed
|
||||
gtk_widget_get_modifier_mask
|
||||
gtk_widget_insert_action_group
|
||||
|
||||
<SUBSECTION>
|
||||
gtk_widget_get_path
|
||||
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
@@ -48,6 +48,9 @@
|
||||
<link linkend="GtkLabel">
|
||||
<inlinegraphic fileref="label.png" format="PNG"></inlinegraphic>
|
||||
</link>
|
||||
<link linkend="GtkLevelBar">
|
||||
<inlinegraphic fileref="levelbar.png" format="PNG"></inlinegraphic>
|
||||
</link>
|
||||
<link linkend="GtkLinkButton">
|
||||
<inlinegraphic fileref="link-button.png" format="PNG"></inlinegraphic>
|
||||
</link>
|
||||
|
||||
@@ -228,20 +228,25 @@ static WidgetInfo *
|
||||
create_menu_button (void)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
GtkWidget *align;
|
||||
GtkWidget *image;
|
||||
GtkWidget *menu;
|
||||
GtkWidget *vbox;
|
||||
|
||||
widget = gtk_menu_button_new ();
|
||||
image = gtk_image_new ();
|
||||
gtk_image_set_from_icon_name (GTK_IMAGE (image), "emblem-system-symbolic", GTK_ICON_SIZE_MENU);
|
||||
gtk_button_set_image (GTK_BUTTON (widget), image);
|
||||
menu = gtk_menu_new ();
|
||||
gtk_menu_button_set_menu (GTK_MENU_BUTTON (widget), menu);
|
||||
align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
|
||||
gtk_container_add (GTK_CONTAINER (align), widget);
|
||||
gtk_menu_button_set_popup (GTK_MENU_BUTTON (widget), menu);
|
||||
|
||||
return new_widget_info ("menu-button", align, SMALL);
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 3);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0);
|
||||
gtk_widget_set_halign (widget, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (widget, GTK_ALIGN_CENTER);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new ("Menu Button"), TRUE, TRUE, 0);
|
||||
|
||||
return new_widget_info ("menu-button", vbox, SMALL);
|
||||
}
|
||||
|
||||
#define G_TYPE_TEST_PERMISSION (g_test_permission_get_type ())
|
||||
@@ -282,14 +287,20 @@ g_test_permission_class_init (GTestPermissionClass *class)
|
||||
static WidgetInfo *
|
||||
create_lockbutton (void)
|
||||
{
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *widget;
|
||||
GtkWidget *align;
|
||||
|
||||
widget = gtk_lock_button_new (g_object_new (G_TYPE_TEST_PERMISSION, NULL));
|
||||
align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
|
||||
gtk_container_add (GTK_CONTAINER (align), widget);
|
||||
|
||||
return new_widget_info ("lock-button", align, SMALL);
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 3);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (vbox),
|
||||
gtk_label_new ("Lock Button"),
|
||||
FALSE, FALSE, 0);
|
||||
gtk_widget_set_halign (vbox, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (vbox, GTK_ALIGN_CENTER);
|
||||
|
||||
return new_widget_info ("lock-button", vbox, SMALL);
|
||||
}
|
||||
|
||||
static WidgetInfo *
|
||||
@@ -987,6 +998,24 @@ create_progressbar (void)
|
||||
return new_widget_info ("progressbar", vbox, SMALL);
|
||||
}
|
||||
|
||||
static WidgetInfo *
|
||||
create_level_bar (void)
|
||||
{
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = gtk_level_bar_new ();
|
||||
gtk_level_bar_set_value (GTK_LEVEL_BAR (widget), 0.333);
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 3);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), widget, TRUE, FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (vbox),
|
||||
gtk_label_new ("Level Bar"),
|
||||
FALSE, FALSE, 0);
|
||||
|
||||
return new_widget_info ("levelbar", vbox, SMALL);
|
||||
}
|
||||
|
||||
static WidgetInfo *
|
||||
create_scrolledwindow (void)
|
||||
{
|
||||
@@ -1269,6 +1298,7 @@ get_all_widgets (void)
|
||||
retval = g_list_prepend (retval, create_colorchooserdialog ());
|
||||
retval = g_list_prepend (retval, create_menu_button ());
|
||||
retval = g_list_prepend (retval, create_search_entry ());
|
||||
retval = g_list_prepend (retval, create_level_bar ());
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -53,7 +53,8 @@ noinst_PROGRAMS = \
|
||||
hello-world \
|
||||
window-default \
|
||||
bloatpad \
|
||||
plugman \
|
||||
plugman \
|
||||
sunny \
|
||||
grid-packing \
|
||||
drawing \
|
||||
builder
|
||||
|
||||
@@ -0,0 +1,213 @@
|
||||
#include <stdlib.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static void
|
||||
new_window (GApplication *app,
|
||||
GFile *file)
|
||||
{
|
||||
GtkWidget *window, *scrolled, *view, *overlay;
|
||||
GtkSettings *settings;
|
||||
gboolean appmenu;
|
||||
|
||||
window = gtk_application_window_new (GTK_APPLICATION (app));
|
||||
gtk_application_window_set_show_menubar (GTK_APPLICATION_WINDOW (window), FALSE);
|
||||
gtk_window_set_default_size ((GtkWindow*)window, 640, 480);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Sunny");
|
||||
|
||||
overlay = gtk_overlay_new ();
|
||||
gtk_container_add (GTK_CONTAINER (window), overlay);
|
||||
|
||||
settings = gtk_settings_get_default ();
|
||||
g_object_get (settings, "gtk-shell-shows-app-menu", &appmenu, NULL);
|
||||
if (!appmenu)
|
||||
{
|
||||
GMenuModel *model;
|
||||
GtkWidget *menu;
|
||||
GtkWidget *image;
|
||||
|
||||
model = gtk_application_get_app_menu (GTK_APPLICATION (app));
|
||||
menu = gtk_menu_button_new ();
|
||||
gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (menu), model);
|
||||
gtk_widget_set_halign (menu, GTK_ALIGN_END);
|
||||
gtk_widget_set_valign (menu, GTK_ALIGN_START);
|
||||
image = gtk_image_new ();
|
||||
gtk_image_set_from_icon_name (GTK_IMAGE (image),
|
||||
"sunny",
|
||||
GTK_ICON_SIZE_MENU);
|
||||
gtk_button_set_image (GTK_BUTTON (menu), image);
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), menu);
|
||||
}
|
||||
|
||||
scrolled = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_widget_set_hexpand (scrolled, TRUE);
|
||||
gtk_widget_set_vexpand (scrolled, TRUE);
|
||||
view = gtk_text_view_new ();
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (scrolled), view);
|
||||
gtk_container_add (GTK_CONTAINER (overlay), scrolled);
|
||||
|
||||
if (file != NULL)
|
||||
{
|
||||
gchar *contents;
|
||||
gsize length;
|
||||
|
||||
if (g_file_load_contents (file, NULL, &contents, &length, NULL, NULL))
|
||||
{
|
||||
GtkTextBuffer *buffer;
|
||||
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
||||
gtk_text_buffer_set_text (buffer, contents, length);
|
||||
g_free (contents);
|
||||
}
|
||||
}
|
||||
|
||||
gtk_widget_show_all (GTK_WIDGET (window));
|
||||
}
|
||||
|
||||
static void
|
||||
activate (GApplication *application)
|
||||
{
|
||||
new_window (application, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
open (GApplication *application,
|
||||
GFile **files,
|
||||
gint n_files,
|
||||
const gchar *hint)
|
||||
{
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < n_files; i++)
|
||||
new_window (application, files[i]);
|
||||
}
|
||||
|
||||
typedef GtkApplication MenuButton;
|
||||
typedef GtkApplicationClass MenuButtonClass;
|
||||
|
||||
G_DEFINE_TYPE (MenuButton, menu_button, GTK_TYPE_APPLICATION)
|
||||
|
||||
static void
|
||||
show_about (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
gtk_show_about_dialog (NULL,
|
||||
"program-name", "Sunny",
|
||||
"title", "About Sunny",
|
||||
"logo-icon-name", "sunny",
|
||||
"comments", "A cheap Bloatpad clone.",
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
quit_app (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
GList *list, *next;
|
||||
GtkWindow *win;
|
||||
|
||||
g_print ("Going down...\n");
|
||||
|
||||
list = gtk_application_get_windows (GTK_APPLICATION (g_application_get_default ()));
|
||||
while (list)
|
||||
{
|
||||
win = list->data;
|
||||
next = list->next;
|
||||
|
||||
gtk_widget_destroy (GTK_WIDGET (win));
|
||||
|
||||
list = next;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
new_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
GApplication *app = user_data;
|
||||
|
||||
g_application_activate (app);
|
||||
}
|
||||
|
||||
static GActionEntry app_entries[] = {
|
||||
{ "about", show_about, NULL, NULL, NULL },
|
||||
{ "quit", quit_app, NULL, NULL, NULL },
|
||||
{ "new", new_activated, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
static void
|
||||
startup (GApplication *application)
|
||||
{
|
||||
GtkBuilder *builder;
|
||||
|
||||
G_APPLICATION_CLASS (menu_button_parent_class)->startup (application);
|
||||
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (application), app_entries, G_N_ELEMENTS (app_entries), application);
|
||||
|
||||
builder = gtk_builder_new ();
|
||||
gtk_builder_add_from_string (builder,
|
||||
"<interface>"
|
||||
" <menu id='app-menu'>"
|
||||
" <section>"
|
||||
" <item>"
|
||||
" <attribute name='label' translatable='yes'>_New Window</attribute>"
|
||||
" <attribute name='action'>app.new</attribute>"
|
||||
" </item>"
|
||||
" <item>"
|
||||
" <attribute name='label' translatable='yes'>_About Sunny</attribute>"
|
||||
" <attribute name='action'>app.about</attribute>"
|
||||
" </item>"
|
||||
" <item>"
|
||||
" <attribute name='label' translatable='yes'>_Quit</attribute>"
|
||||
" <attribute name='action'>app.quit</attribute>"
|
||||
" <attribute name='accel'><Primary>q</attribute>"
|
||||
" </item>"
|
||||
" </section>"
|
||||
" </menu>"
|
||||
"</interface>", -1, NULL);
|
||||
gtk_application_set_app_menu (GTK_APPLICATION (application), G_MENU_MODEL (gtk_builder_get_object (builder, "app-menu")));
|
||||
g_object_unref (builder);
|
||||
}
|
||||
|
||||
static void
|
||||
menu_button_init (MenuButton *app)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
menu_button_class_init (MenuButtonClass *class)
|
||||
{
|
||||
GApplicationClass *application_class = G_APPLICATION_CLASS (class);
|
||||
|
||||
application_class->startup = startup;
|
||||
application_class->activate = activate;
|
||||
application_class->open = open;
|
||||
}
|
||||
|
||||
MenuButton *
|
||||
menu_button_new (void)
|
||||
{
|
||||
g_type_init ();
|
||||
|
||||
return g_object_new (menu_button_get_type (),
|
||||
"application-id", "org.gtk.Test.Sunny",
|
||||
"flags", G_APPLICATION_HANDLES_OPEN,
|
||||
NULL);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
MenuButton *menu_button;
|
||||
int status;
|
||||
|
||||
menu_button = menu_button_new ();
|
||||
status = g_application_run (G_APPLICATION (menu_button), argc, argv);
|
||||
g_object_unref (menu_button);
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -58,12 +58,12 @@ gdk_event_source_prepare (GSource *source,
|
||||
GdkDisplay *display = ((GdkEventSource*) source)->display;
|
||||
gboolean retval;
|
||||
|
||||
GDK_THREADS_ENTER ();
|
||||
gdk_threads_enter ();
|
||||
|
||||
*timeout = -1;
|
||||
retval = (_gdk_event_queue_find_first (display) != NULL);
|
||||
|
||||
GDK_THREADS_LEAVE ();
|
||||
gdk_threads_leave ();
|
||||
|
||||
return retval;
|
||||
}
|
||||
@@ -74,14 +74,14 @@ gdk_event_source_check (GSource *source)
|
||||
GdkEventSource *event_source = (GdkEventSource*) source;
|
||||
gboolean retval;
|
||||
|
||||
GDK_THREADS_ENTER ();
|
||||
gdk_threads_enter ();
|
||||
|
||||
if (event_source->event_poll_fd.revents & G_IO_IN)
|
||||
retval = (_gdk_event_queue_find_first (event_source->display) != NULL);
|
||||
else
|
||||
retval = FALSE;
|
||||
|
||||
GDK_THREADS_LEAVE ();
|
||||
gdk_threads_leave ();
|
||||
|
||||
return retval;
|
||||
}
|
||||
@@ -353,7 +353,7 @@ gdk_event_source_dispatch (GSource *source,
|
||||
GdkDisplay *display = ((GdkEventSource*) source)->display;
|
||||
GdkEvent *event;
|
||||
|
||||
GDK_THREADS_ENTER ();
|
||||
gdk_threads_enter ();
|
||||
|
||||
event = gdk_display_get_event (display);
|
||||
|
||||
@@ -364,7 +364,7 @@ gdk_event_source_dispatch (GSource *source,
|
||||
gdk_event_free (event);
|
||||
}
|
||||
|
||||
GDK_THREADS_LEAVE ();
|
||||
gdk_threads_leave ();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#define GDK_DISABLE_DEPRECATION_WARNINGS 1
|
||||
|
||||
#include "gdkmain.h"
|
||||
|
||||
#include "gdkinternals.h"
|
||||
@@ -446,10 +448,6 @@ gdk_init (int *argc, char ***argv)
|
||||
* which protects all use of GTK+. That is, only one thread can use GTK+
|
||||
* at any given time.
|
||||
*
|
||||
* Unfortunately the above holds with the X11 backend only. With the
|
||||
* Win32 backend, GDK calls should not be attempted from multiple threads
|
||||
* at all.
|
||||
*
|
||||
* You must call gdk_threads_init() before executing any other GTK+ or
|
||||
* GDK functions in a threaded GTK+ program.
|
||||
*
|
||||
@@ -651,6 +649,21 @@ gdk_init (int *argc, char ***argv)
|
||||
* }
|
||||
* </programlisting>
|
||||
* </informalexample>
|
||||
*
|
||||
* Unfortunately, all of the above documentation holds with the X11
|
||||
* backend only. With the Win32 backend, GDK and GTK+ calls should not
|
||||
* be attempted from multiple threads at all. Combining the GDK lock
|
||||
* with other locks such as the Python global interpreter lock can be
|
||||
* complicated.
|
||||
*
|
||||
* For these reason, the threading support has been deprecated in
|
||||
* GTK+ 3.6. Instead of calling GTK+ directly from multiple threads,
|
||||
* it is recommended to use g_idle_add(), g_main_context_invoke()
|
||||
* and similar functions to make these calls from the main thread
|
||||
* instead. The main thread is the thread which has called gtk_init()
|
||||
* and is running the GTK+ mainloop. GTK+ itself will continue to
|
||||
* use the GDK lock internally as long as the deprecated functionality
|
||||
* is still available, and other libraries should probably do the same.
|
||||
*/
|
||||
|
||||
|
||||
@@ -661,6 +674,9 @@ gdk_init (int *argc, char ***argv)
|
||||
* GDK and GTK+ functions can be called safely and without causing race
|
||||
* conditions. Only one thread at a time can be in such a critial
|
||||
* section.
|
||||
*
|
||||
* Deprecated:3.6: All GDK and GTK+ calls should be made from the main
|
||||
* thread
|
||||
*/
|
||||
void
|
||||
gdk_threads_enter (void)
|
||||
@@ -673,6 +689,9 @@ gdk_threads_enter (void)
|
||||
* gdk_threads_leave:
|
||||
*
|
||||
* Leaves a critical region begun with gdk_threads_enter().
|
||||
*
|
||||
* Deprecated:3.6: All GDK and GTK+ calls should be made from the main
|
||||
* thread
|
||||
*/
|
||||
void
|
||||
gdk_threads_leave (void)
|
||||
@@ -701,6 +720,9 @@ gdk_threads_impl_unlock (void)
|
||||
*
|
||||
* This call must be made before any use of the main loop from
|
||||
* GTK+; to be safe, call it before gtk_init().
|
||||
*
|
||||
* Deprecated:3.6: All GDK and GTK+ calls should be made from the main
|
||||
* thread
|
||||
*/
|
||||
void
|
||||
gdk_threads_init (void)
|
||||
@@ -738,6 +760,9 @@ gdk_threads_init (void)
|
||||
* This method must be called before gdk_threads_init(), and cannot
|
||||
* be called multiple times.
|
||||
*
|
||||
* Deprecated:3.6: All GDK and GTK+ calls should be made from the main
|
||||
* thread
|
||||
*
|
||||
* Since: 2.4
|
||||
**/
|
||||
void
|
||||
@@ -757,12 +782,12 @@ gdk_threads_dispatch (gpointer data)
|
||||
GdkThreadsDispatch *dispatch = data;
|
||||
gboolean ret = FALSE;
|
||||
|
||||
GDK_THREADS_ENTER ();
|
||||
gdk_threads_enter ();
|
||||
|
||||
if (!g_source_is_destroyed (g_main_current_source ()))
|
||||
ret = dispatch->func (dispatch->data);
|
||||
|
||||
GDK_THREADS_LEAVE ();
|
||||
gdk_threads_leave ();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -33,9 +33,19 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#if defined(GDK_COMPILATION) || defined(GTK_COMPILATION)
|
||||
#define GDK_THREADS_DEPRECATED
|
||||
#else
|
||||
#define GDK_THREADS_DEPRECATED GDK_DEPRECATED_IN_3_6
|
||||
#endif
|
||||
|
||||
GDK_THREADS_DEPRECATED
|
||||
void gdk_threads_init (void);
|
||||
GDK_THREADS_DEPRECATED
|
||||
void gdk_threads_enter (void);
|
||||
GDK_THREADS_DEPRECATED
|
||||
void gdk_threads_leave (void);
|
||||
GDK_THREADS_DEPRECATED
|
||||
void gdk_threads_set_lock_functions (GCallback enter_fn,
|
||||
GCallback leave_fn);
|
||||
|
||||
@@ -62,6 +72,7 @@ guint gdk_threads_add_timeout_seconds (guint interval,
|
||||
GSourceFunc function,
|
||||
gpointer data);
|
||||
|
||||
|
||||
/**
|
||||
* GDK_THREADS_ENTER:
|
||||
*
|
||||
@@ -71,6 +82,9 @@ guint gdk_threads_add_timeout_seconds (guint interval,
|
||||
* section. The macro expands to a no-op if #G_THREADS_ENABLED has not
|
||||
* been defined. Typically gdk_threads_enter() should be used instead of
|
||||
* this macro.
|
||||
*
|
||||
* Deprecated:3.6: Use g_main_context_invoke(), g_idle_add() and related
|
||||
* functions if you need to schedule GTK+ calls from other threads.
|
||||
*/
|
||||
#define GDK_THREADS_ENTER() gdk_threads_enter()
|
||||
|
||||
@@ -79,9 +93,13 @@ guint gdk_threads_add_timeout_seconds (guint interval,
|
||||
*
|
||||
* This macro marks the end of a critical section
|
||||
* begun with #GDK_THREADS_ENTER.
|
||||
*
|
||||
* Deprecated:3.6: Deprecated in 3.6.
|
||||
*/
|
||||
#define GDK_THREADS_LEAVE() gdk_threads_leave()
|
||||
|
||||
#undef GDK_THREADS_DEPRECATED
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_THREADS_H__ */
|
||||
|
||||
@@ -254,6 +254,7 @@ static void gdk_window_invalidate_rect_full (GdkWindow *window,
|
||||
gboolean invalidate_children,
|
||||
ClearBg clear_bg);
|
||||
static void _gdk_window_propagate_has_alpha_background (GdkWindow *window);
|
||||
static cairo_surface_t *gdk_window_ref_impl_surface (GdkWindow *window);
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
@@ -263,6 +264,42 @@ static const cairo_user_data_key_t gdk_window_cairo_key;
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE (GdkWindow, gdk_window, G_TYPE_OBJECT)
|
||||
|
||||
#ifdef DEBUG_WINDOW_PRINTING
|
||||
char *
|
||||
print_region (cairo_region_t *region)
|
||||
{
|
||||
GString *s = g_string_new ("{");
|
||||
if (cairo_region_is_empty (region))
|
||||
{
|
||||
g_string_append (s, "empty");
|
||||
}
|
||||
else
|
||||
{
|
||||
int num = cairo_region_num_rectangles (region);
|
||||
cairo_rectangle_int_t r;
|
||||
|
||||
if (num == 1)
|
||||
{
|
||||
cairo_region_get_rectangle (region, 0, &r);
|
||||
g_string_append_printf (s, "%dx%d @%d,%d", r.width, r.height, r.x, r.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
cairo_region_get_extents (region, &r);
|
||||
g_string_append_printf (s, "extent: %dx%d @%d,%d, details: ", r.width, r.height, r.x, r.y);
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
g_string_append_printf (s, "[%dx%d @%d,%d]", r.width, r.height, r.x, r.y);
|
||||
if (i != num -1)
|
||||
g_string_append (s, ", ");
|
||||
}
|
||||
}
|
||||
}
|
||||
g_string_append (s, "}");
|
||||
return g_string_free (s, FALSE);
|
||||
}
|
||||
#endif
|
||||
|
||||
GType
|
||||
_gdk_paintable_get_type (void)
|
||||
{
|
||||
@@ -2671,7 +2708,7 @@ gdk_window_get_content (GdkWindow *window)
|
||||
|
||||
g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
|
||||
|
||||
surface = _gdk_window_ref_cairo_surface (window);
|
||||
surface = gdk_window_ref_impl_surface (window);
|
||||
content = cairo_surface_get_content (surface);
|
||||
cairo_surface_destroy (surface);
|
||||
|
||||
@@ -2746,60 +2783,55 @@ gdk_cairo_create_for_impl (GdkWindow *window)
|
||||
return cr;
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
/* This is called whenever something is drawing directly to the
|
||||
* window, bypassing the double buffering. When this happens we
|
||||
* need to mark any the currently drawn data in the double buffer
|
||||
* as invalid to avoid later drawing it back over the directly
|
||||
* rendered pixels. We also need to mark this region as "flushed"
|
||||
* so that if we later try to paint on it double-buffered we need
|
||||
* to read back the on-window pixels rather than relying on what
|
||||
* is in the current double-buffer pixmap.
|
||||
*
|
||||
* Note that this doesn't correctly handle the case where the
|
||||
* non-double buffered drawing uses transparency and relies on
|
||||
* what the windows below it draws. A fix for that would require
|
||||
* drawing the existing double-buffered background to the window,
|
||||
* but that causes ugly flashes. Non-double buffered drawing is
|
||||
* typically only used in old code or when the drawed widget
|
||||
* already has a double-buffering layer, and in these cases the
|
||||
* pixels are opaque anyway. If you need transparency, don't
|
||||
* disable double buffering.
|
||||
*/
|
||||
static void
|
||||
gdk_window_flush_implicit_paint (GdkWindow *window)
|
||||
{
|
||||
GdkWindow *impl_window;
|
||||
GdkWindowPaint *paint;
|
||||
cairo_region_t *region;
|
||||
GSList *list;
|
||||
|
||||
impl_window = gdk_window_get_impl_window (window);
|
||||
if (impl_window->implicit_paint == NULL)
|
||||
return;
|
||||
|
||||
paint = impl_window->implicit_paint;
|
||||
region = cairo_region_copy (window->clip_region_with_children);
|
||||
|
||||
region = cairo_region_copy (window->clip_region_with_children);
|
||||
cairo_region_translate (region, window->abs_x, window->abs_y);
|
||||
|
||||
/* Anything in the whole flushed window that was drawn is now
|
||||
considered unpainted, so that we don't push it back at the
|
||||
end of the implicit paint overwriting the directly rendered
|
||||
pixels. */
|
||||
cairo_region_subtract (paint->region, region);
|
||||
|
||||
/* Save flushed area so we can read it back if we draw over it later */
|
||||
if (paint->flushed == NULL)
|
||||
paint->flushed = cairo_region_copy (region);
|
||||
paint->flushed = region;
|
||||
else
|
||||
cairo_region_union (paint->flushed, region);
|
||||
|
||||
cairo_region_intersect (region, paint->region);
|
||||
|
||||
/* Don't flush active double buffers, as that may show partially done
|
||||
* rendering */
|
||||
for (list = window->paint_stack; list != NULL; list = list->next)
|
||||
{
|
||||
GdkWindowPaint *tmp_paint = list->data;
|
||||
|
||||
cairo_region_subtract (region, tmp_paint->region);
|
||||
cairo_region_union (paint->flushed, region);
|
||||
cairo_region_destroy (region);
|
||||
}
|
||||
|
||||
if (!GDK_WINDOW_DESTROYED (window) && !cairo_region_is_empty (region))
|
||||
{
|
||||
cairo_t *cr;
|
||||
|
||||
/* Remove flushed region from the implicit paint */
|
||||
cairo_region_subtract (paint->region, region);
|
||||
|
||||
/* Some regions are valid, push these to window now */
|
||||
cr = gdk_cairo_create_for_impl (window);
|
||||
gdk_cairo_region (cr, region);
|
||||
cairo_clip (cr);
|
||||
cairo_set_source_surface (cr, paint->surface, 0, 0);
|
||||
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_paint (cr);
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
|
||||
cairo_region_destroy (region);
|
||||
}
|
||||
|
||||
/* Ends an implicit paint, paired with gdk_window_begin_implicit_paint returning TRUE */
|
||||
@@ -3412,28 +3444,6 @@ gdk_window_flush (GdkWindow *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)
|
||||
{
|
||||
GdkWindow *impl_window;
|
||||
|
||||
impl_window = gdk_window_get_impl_window (window);
|
||||
|
||||
/* 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 (GdkWindow *window,
|
||||
GdkWindowImpl *impl)
|
||||
@@ -5334,8 +5344,6 @@ gdk_window_raise (GdkWindow *window)
|
||||
if (window->destroyed)
|
||||
return;
|
||||
|
||||
gdk_window_flush_if_exposing (window);
|
||||
|
||||
/* Keep children in (reverse) stacking order */
|
||||
gdk_window_raise_internal (window);
|
||||
|
||||
@@ -5456,8 +5464,6 @@ gdk_window_lower (GdkWindow *window)
|
||||
if (window->destroyed)
|
||||
return;
|
||||
|
||||
gdk_window_flush_if_exposing (window);
|
||||
|
||||
/* Keep children in (reverse) stacking order */
|
||||
gdk_window_lower_internal (window);
|
||||
|
||||
@@ -5513,8 +5519,6 @@ gdk_window_restack (GdkWindow *window,
|
||||
return;
|
||||
}
|
||||
|
||||
gdk_window_flush_if_exposing (window);
|
||||
|
||||
if (gdk_window_is_toplevel (window))
|
||||
{
|
||||
g_return_if_fail (gdk_window_is_toplevel (sibling));
|
||||
@@ -6070,8 +6074,6 @@ gdk_window_move_resize_internal (GdkWindow *window,
|
||||
window->y == y)))
|
||||
return;
|
||||
|
||||
gdk_window_flush_if_exposing (window);
|
||||
|
||||
/* Handle child windows */
|
||||
|
||||
expose = FALSE;
|
||||
@@ -6356,8 +6358,6 @@ gdk_window_scroll (GdkWindow *window,
|
||||
if (window->destroyed)
|
||||
return;
|
||||
|
||||
gdk_window_flush_if_exposing (window);
|
||||
|
||||
old_layered_area = cairo_region_copy (window->layered_region);
|
||||
old_native_child_region = collect_native_child_region (window, FALSE);
|
||||
if (old_native_child_region)
|
||||
@@ -9812,11 +9812,16 @@ proxy_button_event (GdkEvent *source_event,
|
||||
}
|
||||
|
||||
#ifdef DEBUG_WINDOW_PRINTING
|
||||
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
#include "x11/gdkx.h"
|
||||
#endif
|
||||
|
||||
static void
|
||||
gdk_window_print (GdkWindow *window,
|
||||
int indent)
|
||||
{
|
||||
GdkRectangle r;
|
||||
char *s;
|
||||
const char *window_types[] = {
|
||||
"root",
|
||||
"toplevel",
|
||||
@@ -9855,11 +9860,8 @@ gdk_window_print (GdkWindow *window,
|
||||
g_print (" abs[%d,%d]",
|
||||
window->abs_x, window->abs_y);
|
||||
|
||||
cairo_region_get_extents (window->clip_region, &r);
|
||||
if (cairo_region_is_empty (window->clip_region))
|
||||
g_print (" clipbox[empty]");
|
||||
else
|
||||
g_print (" clipbox[%d,%d %dx%d]", r.x, r.y, r.width, r.height);
|
||||
s = print_region (window->clip_region);
|
||||
g_print (" clipbox[%s]", s);
|
||||
|
||||
g_print ("\n");
|
||||
}
|
||||
@@ -10129,7 +10131,7 @@ gdk_window_create_similar_surface (GdkWindow * window,
|
||||
|
||||
g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
|
||||
|
||||
window_surface = _gdk_window_ref_cairo_surface (window);
|
||||
window_surface = gdk_window_ref_impl_surface (window);
|
||||
|
||||
switch (_gdk_rendering_mode)
|
||||
{
|
||||
|
||||
@@ -616,14 +616,14 @@ gdk_event_prepare (GSource *source,
|
||||
{
|
||||
gboolean retval;
|
||||
|
||||
GDK_THREADS_ENTER ();
|
||||
gdk_threads_enter ();
|
||||
|
||||
*timeout = -1;
|
||||
|
||||
retval = (_gdk_event_queue_find_first (_gdk_display) != NULL ||
|
||||
_gdk_quartz_event_loop_check_pending ());
|
||||
|
||||
GDK_THREADS_LEAVE ();
|
||||
gdk_threads_leave ();
|
||||
|
||||
return retval;
|
||||
}
|
||||
@@ -633,7 +633,7 @@ gdk_event_check (GSource *source)
|
||||
{
|
||||
gboolean retval;
|
||||
|
||||
GDK_THREADS_ENTER ();
|
||||
gdk_threads_enter ();
|
||||
|
||||
/* Refresh the autorelease pool if we're at the base CFRunLoop level
|
||||
* (indicated by current_loop_level) and the base g_main_loop level
|
||||
@@ -653,7 +653,7 @@ gdk_event_check (GSource *source)
|
||||
retval = (_gdk_event_queue_find_first (_gdk_display) != NULL ||
|
||||
_gdk_quartz_event_loop_check_pending ());
|
||||
|
||||
GDK_THREADS_LEAVE ();
|
||||
gdk_threads_leave ();
|
||||
|
||||
return retval;
|
||||
}
|
||||
@@ -665,7 +665,7 @@ gdk_event_dispatch (GSource *source,
|
||||
{
|
||||
GdkEvent *event;
|
||||
|
||||
GDK_THREADS_ENTER ();
|
||||
gdk_threads_enter ();
|
||||
|
||||
_gdk_quartz_display_queue_events (_gdk_display);
|
||||
|
||||
@@ -678,7 +678,7 @@ gdk_event_dispatch (GSource *source,
|
||||
gdk_event_free (event);
|
||||
}
|
||||
|
||||
GDK_THREADS_LEAVE ();
|
||||
gdk_threads_leave ();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -172,8 +172,11 @@ static guint32
|
||||
get_time_from_ns_event (NSEvent *event)
|
||||
{
|
||||
double time = [event timestamp];
|
||||
|
||||
return time * 1000.0;
|
||||
|
||||
/* cast via double->uint64 conversion to make sure that it is
|
||||
* wrapped on 32-bit machines when it overflows
|
||||
*/
|
||||
return (guint32) (guint64) (time * 1000.0);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1478,9 +1481,9 @@ _gdk_quartz_display_queue_events (GdkDisplay *display)
|
||||
g_list_free_1 (node);
|
||||
gdk_event_free (event);
|
||||
|
||||
GDK_THREADS_LEAVE ();
|
||||
gdk_threads_leave ();
|
||||
[NSApp sendEvent:nsevent];
|
||||
GDK_THREADS_ENTER ();
|
||||
gdk_threads_enter ();
|
||||
}
|
||||
|
||||
_gdk_quartz_event_loop_release_event (nsevent);
|
||||
|
||||
@@ -629,17 +629,15 @@ gdk_quartz_keymap_get_entries_for_keycode (GdkKeymap *keymap,
|
||||
return *n_entries > 0;
|
||||
}
|
||||
|
||||
#define GET_KEYVAL(keycode, group, level) (keyval_array[(keycode * KEYVALS_PER_KEYCODE + group * 2 + level)])
|
||||
|
||||
static guint
|
||||
gdk_quartz_keymap_lookup_key (GdkKeymap *keymap,
|
||||
const GdkKeymapKey *key)
|
||||
{
|
||||
/* FIXME: Implement */
|
||||
|
||||
return 0;
|
||||
return GET_KEYVAL (key->keycode, key->group, key->level);
|
||||
}
|
||||
|
||||
#define GET_KEYVAL(keycode, group, level) (keyval_array[(keycode * KEYVALS_PER_KEYCODE + group * 2 + level)])
|
||||
|
||||
static guint
|
||||
translate_keysym (guint hardware_keycode,
|
||||
gint group,
|
||||
|
||||
@@ -65,6 +65,8 @@ struct _GdkWaylandDevice
|
||||
GdkDevice *pointer;
|
||||
GdkDevice *keyboard;
|
||||
|
||||
GdkKeymap *keymap;
|
||||
|
||||
GdkModifierType modifiers;
|
||||
GdkWindow *pointer_focus;
|
||||
GdkWindow *keyboard_focus;
|
||||
@@ -376,6 +378,12 @@ _gdk_wayland_device_get_wl_keyboard (GdkDevice *device)
|
||||
return GDK_DEVICE_CORE (device)->device->wl_keyboard;
|
||||
}
|
||||
|
||||
GdkKeymap *
|
||||
_gdk_wayland_device_get_keymap (GdkDevice *device)
|
||||
{
|
||||
return GDK_DEVICE_CORE (device)->device->keymap;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
input_handle_motion(void *data, struct wl_input_device *input_device,
|
||||
@@ -1157,36 +1165,10 @@ keyboard_handle_keymap (void *data,
|
||||
uint32_t size)
|
||||
{
|
||||
GdkWaylandDevice *device = data;
|
||||
GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (device->display);
|
||||
GdkKeymap *gdk_keymap;
|
||||
gchar *keymap_data;
|
||||
struct xkb_keymap *keymap;
|
||||
if (device->keymap)
|
||||
g_object_unref (device->keymap);
|
||||
|
||||
if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1)
|
||||
{
|
||||
g_critical (G_STRLOC ": Unknown keymap format");
|
||||
close (fd);
|
||||
return;
|
||||
}
|
||||
|
||||
keymap_data = mmap (NULL, size, PROT_READ, MAP_SHARED, fd, 0);
|
||||
if (keymap_data == MAP_FAILED)
|
||||
{
|
||||
g_critical (G_STRLOC ": Unable to map fd for keymap %s", g_strerror (errno));
|
||||
close (fd);
|
||||
return;
|
||||
}
|
||||
|
||||
keymap = xkb_map_new_from_string (display->xkb_context,
|
||||
keymap_data,
|
||||
format,
|
||||
0);
|
||||
|
||||
munmap (keymap_data, size);
|
||||
close (fd);
|
||||
|
||||
gdk_keymap = _gdk_wayland_display_get_keymap (device->display);
|
||||
_gdk_wayland_keymap_update_keymap (gdk_keymap, keymap);
|
||||
device->keymap = _gdk_wayland_keymap_new_from_fd (format, fd, size);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1196,7 +1178,6 @@ keyboard_handle_enter (void *data,
|
||||
struct wl_surface *surface,
|
||||
struct wl_array *keys)
|
||||
{
|
||||
|
||||
GdkWaylandDevice *device = data;
|
||||
GdkEvent *event;
|
||||
GdkWaylandDisplay *wayland_display =
|
||||
@@ -1252,6 +1233,177 @@ keyboard_handle_leave (void *data,
|
||||
_gdk_wayland_display_deliver_event (device->display, event);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
keyboard_repeat (gpointer data);
|
||||
|
||||
static GdkModifierType
|
||||
get_modifier (struct xkb_state *state)
|
||||
{
|
||||
GdkModifierType modifiers = 0;
|
||||
modifiers |= (xkb_state_mod_name_is_active (state, XKB_MOD_NAME_SHIFT, XKB_STATE_EFFECTIVE) > 0)?GDK_SHIFT_MASK:0;
|
||||
modifiers |= (xkb_state_mod_name_is_active (state, XKB_MOD_NAME_CAPS, XKB_STATE_EFFECTIVE) > 0)?GDK_LOCK_MASK:0;
|
||||
modifiers |= (xkb_state_mod_name_is_active (state, XKB_MOD_NAME_CTRL, XKB_STATE_EFFECTIVE) > 0)?GDK_CONTROL_MASK:0;
|
||||
modifiers |= (xkb_state_mod_name_is_active (state, XKB_MOD_NAME_ALT, XKB_STATE_EFFECTIVE) > 0)?GDK_MOD1_MASK:0;
|
||||
modifiers |= (xkb_state_mod_name_is_active (state, "Mod2", XKB_STATE_EFFECTIVE) > 0)?GDK_MOD2_MASK:0;
|
||||
modifiers |= (xkb_state_mod_name_is_active (state, "Mod3", XKB_STATE_EFFECTIVE) > 0)?GDK_MOD3_MASK:0;
|
||||
modifiers |= (xkb_state_mod_name_is_active (state, XKB_MOD_NAME_LOGO, XKB_STATE_EFFECTIVE) > 0)?GDK_MOD4_MASK:0;
|
||||
modifiers |= (xkb_state_mod_name_is_active (state, "Mod5", XKB_STATE_EFFECTIVE) > 0)?GDK_MOD5_MASK:0;
|
||||
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
static void
|
||||
translate_keyboard_string (GdkEventKey *event)
|
||||
{
|
||||
gunichar c = 0;
|
||||
gchar buf[7];
|
||||
|
||||
/* Fill in event->string crudely, since various programs
|
||||
* depend on it.
|
||||
*/
|
||||
event->string = NULL;
|
||||
|
||||
if (event->keyval != GDK_KEY_VoidSymbol)
|
||||
c = gdk_keyval_to_unicode (event->keyval);
|
||||
|
||||
if (c)
|
||||
{
|
||||
gsize bytes_written;
|
||||
gint len;
|
||||
|
||||
/* Apply the control key - Taken from Xlib
|
||||
*/
|
||||
if (event->state & GDK_CONTROL_MASK)
|
||||
{
|
||||
if ((c >= '@' && c < '\177') || c == ' ') c &= 0x1F;
|
||||
else if (c == '2')
|
||||
{
|
||||
event->string = g_memdup ("\0\0", 2);
|
||||
event->length = 1;
|
||||
buf[0] = '\0';
|
||||
return;
|
||||
}
|
||||
else if (c >= '3' && c <= '7') c -= ('3' - '\033');
|
||||
else if (c == '8') c = '\177';
|
||||
else if (c == '/') c = '_' & 0x1F;
|
||||
}
|
||||
|
||||
len = g_unichar_to_utf8 (c, buf);
|
||||
buf[len] = '\0';
|
||||
|
||||
event->string = g_locale_from_utf8 (buf, len,
|
||||
NULL, &bytes_written,
|
||||
NULL);
|
||||
if (event->string)
|
||||
event->length = bytes_written;
|
||||
}
|
||||
else if (event->keyval == GDK_KEY_Escape)
|
||||
{
|
||||
event->length = 1;
|
||||
event->string = g_strdup ("\033");
|
||||
}
|
||||
else if (event->keyval == GDK_KEY_Return ||
|
||||
event->keyval == GDK_KEY_KP_Enter)
|
||||
{
|
||||
event->length = 1;
|
||||
event->string = g_strdup ("\r");
|
||||
}
|
||||
|
||||
if (!event->string)
|
||||
{
|
||||
event->length = 0;
|
||||
event->string = g_strdup ("");
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
deliver_key_event(GdkWaylandDevice *device,
|
||||
uint32_t time, uint32_t key, uint32_t state)
|
||||
{
|
||||
GdkEvent *event;
|
||||
struct xkb_state *xkb_state;
|
||||
GdkKeymap *keymap;
|
||||
xkb_keysym_t sym;
|
||||
uint32_t num_syms;
|
||||
const xkb_keysym_t *syms;
|
||||
|
||||
keymap = device->keymap;
|
||||
xkb_state = _gdk_wayland_keymap_get_xkb_state (keymap);
|
||||
|
||||
num_syms = xkb_key_get_syms (xkb_state, key, &syms);
|
||||
sym = XKB_KEY_NoSymbol;
|
||||
if (num_syms == 1)
|
||||
sym = syms[0];
|
||||
|
||||
device->time = time;
|
||||
device->modifiers = get_modifier (xkb_state);
|
||||
|
||||
event = gdk_event_new (state ? GDK_KEY_PRESS : GDK_KEY_RELEASE);
|
||||
event->key.window = device->keyboard_focus?g_object_ref (device->keyboard_focus):NULL;
|
||||
gdk_event_set_device (event, device->keyboard);
|
||||
event->button.time = time;
|
||||
event->key.state = device->modifiers;
|
||||
event->key.group = 0;
|
||||
event->key.hardware_keycode = sym;
|
||||
event->key.keyval = sym;
|
||||
|
||||
event->key.is_modifier = device->modifiers > 0;
|
||||
|
||||
translate_keyboard_string (&event->key);
|
||||
|
||||
_gdk_wayland_display_deliver_event (device->display, event);
|
||||
|
||||
GDK_NOTE (EVENTS,
|
||||
g_message ("keyboard event, code %d, sym %d, "
|
||||
"string %s, mods 0x%x",
|
||||
event->key.hardware_keycode, event->key.keyval,
|
||||
event->key.string, event->key.state));
|
||||
|
||||
device->repeat_count++;
|
||||
device->repeat_key = key;
|
||||
|
||||
if (state == 0)
|
||||
{
|
||||
if (device->repeat_timer)
|
||||
{
|
||||
g_source_remove (device->repeat_timer);
|
||||
device->repeat_timer = 0;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
else if (device->modifiers)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
else switch (device->repeat_count)
|
||||
{
|
||||
case 1:
|
||||
if (device->repeat_timer)
|
||||
{
|
||||
g_source_remove (device->repeat_timer);
|
||||
device->repeat_timer = 0;
|
||||
}
|
||||
|
||||
device->repeat_timer =
|
||||
gdk_threads_add_timeout (400, keyboard_repeat, device);
|
||||
return TRUE;
|
||||
case 2:
|
||||
device->repeat_timer =
|
||||
gdk_threads_add_timeout (80, keyboard_repeat, device);
|
||||
return FALSE;
|
||||
default:
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
keyboard_repeat (gpointer data)
|
||||
{
|
||||
GdkWaylandDevice *device = data;
|
||||
|
||||
return deliver_key_event (device, device->time, device->repeat_key, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
keyboard_handle_key (void *data,
|
||||
struct wl_keyboard *keyboard,
|
||||
@@ -1260,6 +1412,13 @@ keyboard_handle_key (void *data,
|
||||
uint32_t key,
|
||||
uint32_t state_w)
|
||||
{
|
||||
GdkWaylandDevice *device = data;
|
||||
GdkWaylandDisplay *wayland_display =
|
||||
GDK_WAYLAND_DISPLAY (device->display);
|
||||
|
||||
device->repeat_count = 0;
|
||||
_gdk_wayland_display_update_serial (wayland_display, serial);
|
||||
deliver_key_event (data, time, key + 8, state_w);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1271,6 +1430,15 @@ keyboard_handle_modifiers (void *data,
|
||||
uint32_t mods_locked,
|
||||
uint32_t group)
|
||||
{
|
||||
GdkWaylandDevice *device = data;
|
||||
GdkKeymap *keymap;
|
||||
struct xkb_state *xkb_state;
|
||||
|
||||
keymap = device->keymap;
|
||||
xkb_state = _gdk_wayland_keymap_get_xkb_state (keymap);
|
||||
device->modifiers = mods_depressed | mods_latched | mods_locked;
|
||||
|
||||
xkb_state_update_mask (xkb_state, mods_depressed, mods_latched, mods_locked, group, 0, 0);
|
||||
}
|
||||
|
||||
static const struct wl_pointer_listener pointer_listener = {
|
||||
@@ -1386,6 +1554,7 @@ _gdk_wayland_device_manager_add_device (GdkDeviceManager *device_manager,
|
||||
display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
|
||||
device = g_new0 (GdkWaylandDevice, 1);
|
||||
device->keymap = _gdk_wayland_keymap_new ();
|
||||
device->display = display;
|
||||
device->device_manager = device_manager;
|
||||
|
||||
|
||||
@@ -536,15 +536,26 @@ gdk_wayland_display_event_data_free (GdkDisplay *display,
|
||||
GdkKeymap *
|
||||
_gdk_wayland_display_get_keymap (GdkDisplay *display)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland;
|
||||
GdkDeviceManager *device_manager;
|
||||
GList *list, *l;
|
||||
GdkDevice *core_keyboard = NULL;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
|
||||
display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
device_manager = gdk_display_get_device_manager (display);
|
||||
list = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
|
||||
|
||||
if (!display_wayland->keymap)
|
||||
display_wayland->keymap = _gdk_wayland_keymap_new (display);
|
||||
for (l = list; l; l = l->next)
|
||||
{
|
||||
GdkDevice *device;
|
||||
device = list->data;
|
||||
|
||||
return display_wayland->keymap;
|
||||
if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
|
||||
continue;
|
||||
|
||||
core_keyboard = device;
|
||||
break;
|
||||
}
|
||||
|
||||
return core_keyboard?_gdk_wayland_device_get_keymap (core_keyboard):NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -68,7 +68,7 @@ gdk_event_source_dispatch(GSource *base,
|
||||
GdkDisplay *display = source->display;
|
||||
GdkEvent *event;
|
||||
|
||||
GDK_THREADS_ENTER ();
|
||||
gdk_threads_enter ();
|
||||
|
||||
event = gdk_display_get_event (display);
|
||||
|
||||
@@ -79,7 +79,7 @@ gdk_event_source_dispatch(GSource *base,
|
||||
gdk_event_free (event);
|
||||
}
|
||||
|
||||
GDK_THREADS_LEAVE ();
|
||||
gdk_threads_leave ();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -30,13 +30,13 @@
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "gdk.h"
|
||||
#include "gdkwayland.h"
|
||||
|
||||
#include "gdkprivate-wayland.h"
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkdisplay-wayland.h"
|
||||
#include "gdkkeysprivate.h"
|
||||
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
@@ -47,13 +47,9 @@ typedef struct _GdkWaylandKeymapClass GdkWaylandKeymapClass;
|
||||
struct _GdkWaylandKeymap
|
||||
{
|
||||
GdkKeymap parent_instance;
|
||||
GdkModifierType modmap[8];
|
||||
struct xkb_desc *xkb;
|
||||
struct xkb_keymap *keymap;
|
||||
struct xkb_state *state;
|
||||
xkb_mod_mask_t control_mask;
|
||||
xkb_mod_mask_t alt_mask;
|
||||
xkb_mod_mask_t shift_mask;
|
||||
|
||||
struct xkb_keymap *xkb_keymap;
|
||||
struct xkb_state *xkb_state;
|
||||
};
|
||||
|
||||
struct _GdkWaylandKeymapClass
|
||||
@@ -88,13 +84,15 @@ gdk_wayland_keymap_have_bidi_layouts (GdkKeymap *keymap)
|
||||
static gboolean
|
||||
gdk_wayland_keymap_get_caps_lock_state (GdkKeymap *keymap)
|
||||
{
|
||||
return FALSE;
|
||||
return xkb_state_led_name_is_active (GDK_WAYLAND_KEYMAP (keymap)->xkb_state,
|
||||
XKB_LED_NAME_CAPS);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_wayland_keymap_get_num_lock_state (GdkKeymap *keymap)
|
||||
{
|
||||
return FALSE;
|
||||
return xkb_state_led_name_is_active (GDK_WAYLAND_KEYMAP (keymap)->xkb_state,
|
||||
XKB_LED_NAME_NUM);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -103,68 +101,15 @@ gdk_wayland_keymap_get_entries_for_keyval (GdkKeymap *keymap,
|
||||
GdkKeymapKey **keys,
|
||||
gint *n_keys)
|
||||
{
|
||||
#if 0
|
||||
GArray *retval;
|
||||
uint32_t keycode;
|
||||
struct xkb_desc *xkb;
|
||||
|
||||
xkb = GDK_WAYLAND_KEYMAP (keymap)->xkb;
|
||||
keycode = xkb->min_key_code;
|
||||
|
||||
retval = g_array_new (FALSE, FALSE, sizeof (GdkKeymapKey));
|
||||
|
||||
for (keycode = xkb->min_key_code; keycode <= xkb->max_key_code; keycode++)
|
||||
if (n_keys)
|
||||
*n_keys = 1;
|
||||
if (keys)
|
||||
{
|
||||
gint max_shift_levels = XkbKeyGroupsWidth (xkb, keycode);
|
||||
|
||||
gint group = 0;
|
||||
gint level = 0;
|
||||
gint total_syms = XkbKeyNumSyms (xkb, keycode);
|
||||
gint i = 0;
|
||||
uint32_t *entry;
|
||||
|
||||
/* entry is an array with all syms for group 0, all
|
||||
* syms for group 1, etc. and for each group the
|
||||
* shift level syms are in order
|
||||
*/
|
||||
entry = XkbKeySymsPtr (xkb, keycode);
|
||||
|
||||
for (i = 0; i < total_syms; i++)
|
||||
{
|
||||
/* check out our cool loop invariant */
|
||||
g_assert (i == (group * max_shift_levels + level));
|
||||
|
||||
if (entry[i] == keyval)
|
||||
{
|
||||
/* Found a match */
|
||||
GdkKeymapKey key;
|
||||
|
||||
key.keycode = keycode;
|
||||
key.group = group;
|
||||
key.level = level;
|
||||
|
||||
g_array_append_val (retval, key);
|
||||
|
||||
g_assert (XkbKeySymEntry (xkb, keycode, level, group) ==
|
||||
keyval);
|
||||
}
|
||||
|
||||
level++;
|
||||
|
||||
if (level == max_shift_levels)
|
||||
{
|
||||
level = 0;
|
||||
group++;
|
||||
}
|
||||
}
|
||||
*keys = g_new0 (GdkKeymapKey, 1);
|
||||
(*keys)->keycode = keyval;
|
||||
}
|
||||
|
||||
*n_keys = retval->len;
|
||||
*keys = (GdkKeymapKey *) g_array_free (retval, FALSE);
|
||||
|
||||
return *n_keys > 0;
|
||||
#endif
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -174,247 +119,28 @@ gdk_wayland_keymap_get_entries_for_keycode (GdkKeymap *keymap,
|
||||
guint **keyvals,
|
||||
gint *n_entries)
|
||||
{
|
||||
#if 0
|
||||
GArray *key_array;
|
||||
GArray *keyval_array;
|
||||
struct xkb_desc *xkb;
|
||||
gint max_shift_levels;
|
||||
gint group = 0;
|
||||
gint level = 0;
|
||||
gint total_syms;
|
||||
gint i;
|
||||
uint32_t *entry;
|
||||
|
||||
g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), FALSE);
|
||||
g_return_val_if_fail (n_entries != NULL, FALSE);
|
||||
|
||||
xkb = GDK_WAYLAND_KEYMAP (keymap)->xkb;
|
||||
|
||||
if (hardware_keycode < xkb->min_key_code ||
|
||||
hardware_keycode > xkb->max_key_code)
|
||||
{
|
||||
if (keys)
|
||||
*keys = NULL;
|
||||
if (keyvals)
|
||||
*keyvals = NULL;
|
||||
|
||||
*n_entries = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (keys)
|
||||
key_array = g_array_new (FALSE, FALSE, sizeof (GdkKeymapKey));
|
||||
else
|
||||
key_array = NULL;
|
||||
|
||||
if (keyvals)
|
||||
keyval_array = g_array_new (FALSE, FALSE, sizeof (guint));
|
||||
else
|
||||
keyval_array = NULL;
|
||||
|
||||
/* See sec 15.3.4 in XKB docs */
|
||||
max_shift_levels = XkbKeyGroupsWidth (xkb, hardware_keycode);
|
||||
total_syms = XkbKeyNumSyms (xkb, hardware_keycode);
|
||||
|
||||
/* entry is an array with all syms for group 0, all
|
||||
* syms for group 1, etc. and for each group the
|
||||
* shift level syms are in order
|
||||
*/
|
||||
entry = XkbKeySymsPtr (xkb, hardware_keycode);
|
||||
|
||||
for (i = 0; i < total_syms; i++)
|
||||
{
|
||||
/* check out our cool loop invariant */
|
||||
g_assert (i == (group * max_shift_levels + level));
|
||||
|
||||
if (key_array)
|
||||
{
|
||||
GdkKeymapKey key;
|
||||
|
||||
key.keycode = hardware_keycode;
|
||||
key.group = group;
|
||||
key.level = level;
|
||||
|
||||
g_array_append_val (key_array, key);
|
||||
}
|
||||
|
||||
if (keyval_array)
|
||||
g_array_append_val (keyval_array, entry[i]);
|
||||
|
||||
++level;
|
||||
|
||||
if (level == max_shift_levels)
|
||||
{
|
||||
level = 0;
|
||||
++group;
|
||||
}
|
||||
}
|
||||
|
||||
*n_entries = 0;
|
||||
|
||||
if (n_entries)
|
||||
*n_entries = 1;
|
||||
if (keys)
|
||||
{
|
||||
*n_entries = key_array->len;
|
||||
*keys = (GdkKeymapKey*) g_array_free (key_array, FALSE);
|
||||
*keys = g_new0 (GdkKeymapKey, 1);
|
||||
(*keys)->keycode = hardware_keycode;
|
||||
}
|
||||
|
||||
if (keyvals)
|
||||
{
|
||||
*n_entries = keyval_array->len;
|
||||
*keyvals = (guint*) g_array_free (keyval_array, FALSE);
|
||||
*keyvals = g_new0 (guint, 1);
|
||||
(*keyvals)[0] = hardware_keycode;
|
||||
}
|
||||
|
||||
return *n_entries > 0;
|
||||
#endif
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static guint
|
||||
gdk_wayland_keymap_lookup_key (GdkKeymap *keymap,
|
||||
const GdkKeymapKey *key)
|
||||
{
|
||||
#if 0
|
||||
struct xkb_desc *xkb;
|
||||
|
||||
xkb = GDK_WAYLAND_KEYMAP (keymap)->xkb;
|
||||
|
||||
return XkbKeySymEntry (xkb, key->keycode, key->level, key->group);
|
||||
#endif
|
||||
return 0;
|
||||
return key->keycode;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* This is copied straight from XFree86 Xlib, to:
|
||||
* - add the group and level return.
|
||||
* - change the interpretation of mods_rtrn as described
|
||||
* in the docs for gdk_keymap_translate_keyboard_state()
|
||||
* It's unchanged for ease of diff against the Xlib sources; don't
|
||||
* reformat it.
|
||||
*/
|
||||
static int
|
||||
MyEnhancedXkbTranslateKeyCode(struct xkb_desc * xkb,
|
||||
KeyCode key,
|
||||
unsigned int mods,
|
||||
unsigned int * mods_rtrn,
|
||||
uint32_t * keysym_rtrn,
|
||||
int * group_rtrn,
|
||||
int * level_rtrn)
|
||||
{
|
||||
struct xkb_key_type *type;
|
||||
int col,nKeyGroups;
|
||||
unsigned preserve,effectiveGroup;
|
||||
uint32_t *syms;
|
||||
|
||||
if (mods_rtrn!=NULL)
|
||||
*mods_rtrn = 0;
|
||||
|
||||
nKeyGroups= XkbKeyNumGroups(xkb,key);
|
||||
if ((!XkbKeycodeInRange(xkb,key))||(nKeyGroups==0)) {
|
||||
if (keysym_rtrn!=NULL)
|
||||
*keysym_rtrn = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
syms = XkbKeySymsPtr(xkb,key);
|
||||
|
||||
/* find the offset of the effective group */
|
||||
col = 0;
|
||||
effectiveGroup= XkbGroupForCoreState(mods);
|
||||
if ( effectiveGroup>=nKeyGroups ) {
|
||||
unsigned groupInfo= XkbKeyGroupInfo(xkb,key);
|
||||
switch (XkbOutOfRangeGroupAction(groupInfo)) {
|
||||
default:
|
||||
effectiveGroup %= nKeyGroups;
|
||||
break;
|
||||
case XkbClampIntoRange:
|
||||
effectiveGroup = nKeyGroups-1;
|
||||
break;
|
||||
case XkbRedirectIntoRange:
|
||||
effectiveGroup = XkbOutOfRangeGroupNumber(groupInfo);
|
||||
if (effectiveGroup>=nKeyGroups)
|
||||
effectiveGroup= 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
col= effectiveGroup*XkbKeyGroupsWidth(xkb,key);
|
||||
type = XkbKeyKeyType(xkb,key,effectiveGroup);
|
||||
|
||||
preserve= 0;
|
||||
if (type->map) { /* find the column (shift level) within the group */
|
||||
register int i;
|
||||
struct xkb_kt_map_entry *entry;
|
||||
/* ---- Begin section modified for GDK ---- */
|
||||
int found = 0;
|
||||
|
||||
for (i=0,entry=type->map;i<type->map_count;i++,entry++) {
|
||||
if (mods_rtrn) {
|
||||
int bits = 0;
|
||||
unsigned long tmp = entry->mods.mask;
|
||||
while (tmp) {
|
||||
if ((tmp & 1) == 1)
|
||||
bits++;
|
||||
tmp >>= 1;
|
||||
}
|
||||
/* We always add one-modifiers levels to mods_rtrn since
|
||||
* they can't wipe out bits in the state unless the
|
||||
* level would be triggered. But return other modifiers
|
||||
*
|
||||
*/
|
||||
if (bits == 1 || (mods&type->mods.mask)==entry->mods.mask)
|
||||
*mods_rtrn |= entry->mods.mask;
|
||||
}
|
||||
|
||||
if (!found&&entry->active&&((mods&type->mods.mask)==entry->mods.mask)) {
|
||||
col+= entry->level;
|
||||
if (type->preserve)
|
||||
preserve= type->preserve[i].mask;
|
||||
|
||||
if (level_rtrn)
|
||||
*level_rtrn = entry->level;
|
||||
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
/* ---- End section modified for GDK ---- */
|
||||
}
|
||||
|
||||
if (keysym_rtrn!=NULL)
|
||||
*keysym_rtrn= syms[col];
|
||||
if (mods_rtrn) {
|
||||
/* ---- Begin section modified for GDK ---- */
|
||||
*mods_rtrn &= ~preserve;
|
||||
/* ---- End section modified for GDK ---- */
|
||||
|
||||
/* ---- Begin stuff GDK comments out of the original Xlib version ---- */
|
||||
/* This is commented out because xkb_info is a private struct */
|
||||
|
||||
#if 0
|
||||
/* The Motif VTS doesn't get the help callback called if help
|
||||
* is bound to Shift+<whatever>, and it appears as though it
|
||||
* is XkbTranslateKeyCode that is causing the problem. The
|
||||
* core X version of XTranslateKey always OR's in ShiftMask
|
||||
* and LockMask for mods_rtrn, so this "fix" keeps this behavior
|
||||
* and solves the VTS problem.
|
||||
*/
|
||||
if ((xkb->dpy)&&(xkb->dpy->xkb_info)&&
|
||||
(xkb->dpy->xkb_info->xlib_ctrls&XkbLC_AlwaysConsumeShiftAndLock)) { *mods_rtrn|= (ShiftMask|LockMask);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ---- End stuff GDK comments out of the original Xlib version ---- */
|
||||
}
|
||||
|
||||
/* ---- Begin stuff GDK adds to the original Xlib version ---- */
|
||||
|
||||
if (group_rtrn)
|
||||
*group_rtrn = effectiveGroup;
|
||||
|
||||
/* ---- End stuff GDK adds to the original Xlib version ---- */
|
||||
|
||||
return (syms[col] != 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
gdk_wayland_keymap_translate_keyboard_state (GdkKeymap *keymap,
|
||||
guint hardware_keycode,
|
||||
@@ -425,20 +151,11 @@ gdk_wayland_keymap_translate_keyboard_state (GdkKeymap *keymap,
|
||||
gint *level,
|
||||
GdkModifierType *consumed_modifiers)
|
||||
{
|
||||
#if 0
|
||||
GdkWaylandKeymap *wayland_keymap;
|
||||
uint32_t tmp_keyval = 0;
|
||||
guint tmp_modifiers;
|
||||
struct xkb_desc *xkb;
|
||||
|
||||
g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), FALSE);
|
||||
g_return_val_if_fail (group < 4, FALSE);
|
||||
|
||||
wayland_keymap = GDK_WAYLAND_KEYMAP (keymap);
|
||||
xkb = wayland_keymap->xkb;
|
||||
|
||||
if (keyval)
|
||||
*keyval = 0;
|
||||
*keyval = hardware_keycode;
|
||||
if (effective_group)
|
||||
*effective_group = 0;
|
||||
if (level)
|
||||
@@ -446,138 +163,21 @@ gdk_wayland_keymap_translate_keyboard_state (GdkKeymap *keymap,
|
||||
if (consumed_modifiers)
|
||||
*consumed_modifiers = 0;
|
||||
|
||||
if (hardware_keycode < xkb->min_key_code ||
|
||||
hardware_keycode > xkb->max_key_code)
|
||||
return FALSE;
|
||||
|
||||
|
||||
/* replace bits 13 and 14 with the provided group */
|
||||
state &= ~(1 << 13 | 1 << 14);
|
||||
state |= group << 13;
|
||||
|
||||
MyEnhancedXkbTranslateKeyCode (xkb,
|
||||
hardware_keycode,
|
||||
state,
|
||||
&tmp_modifiers,
|
||||
&tmp_keyval,
|
||||
effective_group,
|
||||
level);
|
||||
|
||||
if (state & ~tmp_modifiers & XKB_COMMON_LOCK_MASK)
|
||||
tmp_keyval = gdk_keyval_to_upper (tmp_keyval);
|
||||
|
||||
/* We need to augment the consumed modifiers with LockMask, since
|
||||
* we handle that ourselves, and also with the group bits
|
||||
*/
|
||||
tmp_modifiers |= XKB_COMMON_LOCK_MASK | 1 << 13 | 1 << 14;
|
||||
|
||||
|
||||
if (consumed_modifiers)
|
||||
*consumed_modifiers = tmp_modifiers;
|
||||
|
||||
if (keyval)
|
||||
*keyval = tmp_keyval;
|
||||
|
||||
return tmp_keyval != 0;
|
||||
#endif
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
update_modmap (GdkWaylandKeymap *wayland_keymap)
|
||||
{
|
||||
static struct {
|
||||
const gchar *name;
|
||||
uint32_t atom;
|
||||
GdkModifierType mask;
|
||||
} vmods[] = {
|
||||
{ "Meta", 0, GDK_META_MASK },
|
||||
{ "Super", 0, GDK_SUPER_MASK },
|
||||
{ "Hyper", 0, GDK_HYPER_MASK },
|
||||
{ NULL, 0, 0 }
|
||||
};
|
||||
|
||||
gint i, j, k;
|
||||
|
||||
if (!vmods[0].atom)
|
||||
for (i = 0; vmods[i].name; i++)
|
||||
vmods[i].atom = xkb_atom(vmods[i].name);
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
wayland_keymap->modmap[i] = 1 << i;
|
||||
|
||||
for (i = 0; i < XkbNumVirtualMods; i++)
|
||||
{
|
||||
for (j = 0; vmods[j].atom; j++)
|
||||
{
|
||||
if (wayland_keymap->xkb->names->vmods[i] == vmods[j].atom)
|
||||
{
|
||||
for (k = 0; k < 8; k++)
|
||||
{
|
||||
if (wayland_keymap->xkb->server->vmods[i] & (1 << k))
|
||||
wayland_keymap->modmap[k] |= vmods[j].mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
gdk_wayland_keymap_add_virtual_modifiers (GdkKeymap *keymap,
|
||||
GdkModifierType *state)
|
||||
{
|
||||
GdkWaylandKeymap *wayland_keymap;
|
||||
int i;
|
||||
|
||||
wayland_keymap = GDK_WAYLAND_KEYMAP (keymap);
|
||||
|
||||
for (i = 4; i < 8; i++)
|
||||
{
|
||||
if ((1 << i) & *state)
|
||||
{
|
||||
if (wayland_keymap->modmap[i] & GDK_SUPER_MASK)
|
||||
*state |= GDK_SUPER_MASK;
|
||||
if (wayland_keymap->modmap[i] & GDK_HYPER_MASK)
|
||||
*state |= GDK_HYPER_MASK;
|
||||
if (wayland_keymap->modmap[i] & GDK_META_MASK)
|
||||
*state |= GDK_META_MASK;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_wayland_keymap_map_virtual_modifiers (GdkKeymap *keymap,
|
||||
GdkModifierType *state)
|
||||
{
|
||||
const guint vmods[] = {
|
||||
GDK_SUPER_MASK, GDK_HYPER_MASK, GDK_META_MASK
|
||||
};
|
||||
int i, j;
|
||||
GdkWaylandKeymap *wayland_keymap;
|
||||
gboolean retval = TRUE;
|
||||
|
||||
wayland_keymap = GDK_WAYLAND_KEYMAP (keymap);
|
||||
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
if (*state & vmods[j])
|
||||
{
|
||||
for (i = 4; i < 8; i++)
|
||||
{
|
||||
if (wayland_keymap->modmap[i] & vmods[j])
|
||||
{
|
||||
if (*state & (1 << i))
|
||||
retval = FALSE;
|
||||
else
|
||||
*state |= 1 << i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -605,94 +205,62 @@ _gdk_wayland_keymap_init (GdkWaylandKeymap *keymap)
|
||||
{
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
update_keymaps (GdkWaylandKeymap *keymap)
|
||||
{
|
||||
struct xkb_desc *xkb = keymap->xkb;
|
||||
gint keycode, total_syms, i, modifier;
|
||||
uint32_t *entry;
|
||||
guint mask;
|
||||
|
||||
for (keycode = xkb->min_key_code; keycode <= xkb->max_key_code; keycode++)
|
||||
{
|
||||
total_syms = XkbKeyNumSyms (xkb, keycode);
|
||||
|
||||
entry = XkbKeySymsPtr (xkb, keycode);
|
||||
mask = 0;
|
||||
for (i = 0; i < total_syms; i++)
|
||||
{
|
||||
switch (entry[i]) {
|
||||
case GDK_KEY_Meta_L:
|
||||
case GDK_KEY_Meta_R:
|
||||
mask |= GDK_META_MASK;
|
||||
break;
|
||||
case GDK_KEY_Hyper_L:
|
||||
case GDK_KEY_Hyper_R:
|
||||
mask |= GDK_HYPER_MASK;
|
||||
break;
|
||||
case GDK_KEY_Super_L:
|
||||
case GDK_KEY_Super_R:
|
||||
mask |= GDK_SUPER_MASK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
modifier = g_bit_nth_lsf(xkb->map->modmap[keycode], -1);
|
||||
keymap->modmap[modifier] |= mask;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
GdkKeymap *
|
||||
_gdk_wayland_keymap_new (GdkDisplay *display)
|
||||
_gdk_wayland_keymap_new ()
|
||||
{
|
||||
GdkWaylandKeymap *keymap;
|
||||
struct xkb_context *context;
|
||||
struct xkb_rule_names names;
|
||||
|
||||
keymap = g_object_new (_gdk_wayland_keymap_get_type(), NULL);
|
||||
GDK_KEYMAP (keymap)->display = display;
|
||||
#if 0
|
||||
|
||||
context = xkb_context_new (0);
|
||||
|
||||
names.rules = "evdev";
|
||||
names.model = "pc105";
|
||||
names.layout = "us";
|
||||
names.variant = "";
|
||||
names.options = "";
|
||||
keymap->xkb = xkb_compile_keymap_from_rules(&names);
|
||||
update_modmap (keymap);
|
||||
update_keymaps (keymap);
|
||||
#endif
|
||||
keymap->xkb_keymap = xkb_map_new_from_names(context, &names, XKB_MAP_COMPILE_PLACEHOLDER);
|
||||
keymap->xkb_state = xkb_state_new (keymap->xkb_keymap);
|
||||
xkb_context_unref (context);
|
||||
|
||||
return GDK_KEYMAP (keymap);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_wayland_keymap_update_keymap (GdkKeymap *gdk_keymap,
|
||||
struct xkb_keymap *xkb_keymap)
|
||||
GdkKeymap *
|
||||
_gdk_wayland_keymap_new_from_fd (uint32_t format,
|
||||
uint32_t fd, uint32_t size)
|
||||
{
|
||||
GdkWaylandKeymap *keymap;
|
||||
struct xkb_context *context;
|
||||
char *map_str;
|
||||
|
||||
keymap = GDK_WAYLAND_KEYMAP (gdk_keymap);
|
||||
keymap = g_object_new (_gdk_wayland_keymap_get_type(), NULL);
|
||||
|
||||
if (keymap->keymap)
|
||||
xkb_map_unref (keymap->keymap);
|
||||
context = xkb_context_new (0);
|
||||
|
||||
keymap->keymap = xkb_keymap;
|
||||
map_str = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
|
||||
if (map_str == MAP_FAILED) {
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (keymap->state)
|
||||
xkb_state_unref (keymap->state);
|
||||
keymap->xkb_keymap = xkb_map_new_from_string (context, map_str, format, XKB_MAP_COMPILE_PLACEHOLDER);
|
||||
munmap (map_str, size);
|
||||
close (fd);
|
||||
keymap->xkb_state = xkb_state_new (keymap->xkb_keymap);
|
||||
xkb_context_unref (context);
|
||||
|
||||
keymap->state = xkb_state_new (keymap->keymap);
|
||||
|
||||
keymap->control_mask =
|
||||
1 << xkb_map_mod_get_index(keymap->keymap, "Control");
|
||||
keymap->alt_mask =
|
||||
1 << xkb_map_mod_get_index(keymap->keymap, "Mod1");
|
||||
keymap->shift_mask =
|
||||
1 << xkb_map_mod_get_index(keymap->keymap, "Shift");
|
||||
return GDK_KEYMAP (keymap);
|
||||
}
|
||||
|
||||
struct xkb_desc *_gdk_wayland_keymap_get_xkb_desc (GdkKeymap *keymap)
|
||||
struct xkb_keymap *_gdk_wayland_keymap_get_xkb_keymap (GdkKeymap *keymap)
|
||||
{
|
||||
return GDK_WAYLAND_KEYMAP (keymap)->xkb;
|
||||
return GDK_WAYLAND_KEYMAP (keymap)->xkb_keymap;
|
||||
}
|
||||
|
||||
struct xkb_state *_gdk_wayland_keymap_get_xkb_state (GdkKeymap *keymap)
|
||||
{
|
||||
return GDK_WAYLAND_KEYMAP (keymap)->xkb_state;
|
||||
}
|
||||
|
||||
@@ -48,8 +48,10 @@ GType _gdk_wayland_window_get_type (void);
|
||||
void _gdk_wayland_window_add_focus (GdkWindow *window);
|
||||
void _gdk_wayland_window_remove_focus (GdkWindow *window);
|
||||
|
||||
GdkKeymap *_gdk_wayland_keymap_new (GdkDisplay *display);
|
||||
struct xkb_desc *_gdk_wayland_keymap_get_xkb_desc (GdkKeymap *keymap);
|
||||
GdkKeymap *_gdk_wayland_keymap_new (void);
|
||||
GdkKeymap *_gdk_wayland_keymap_new_from_fd (uint32_t format,
|
||||
uint32_t fd, uint32_t size);
|
||||
struct xkb_state *_gdk_wayland_keymap_get_xkb_state (GdkKeymap *keymap);
|
||||
|
||||
GdkCursor *_gdk_wayland_display_get_cursor_for_type (GdkDisplay *display,
|
||||
GdkCursorType cursor_type);
|
||||
@@ -90,10 +92,6 @@ void _gdk_wayland_display_create_window_impl (GdkDisplay *display,
|
||||
GdkWindowAttr *attributes,
|
||||
gint attributes_mask);
|
||||
|
||||
GdkKeymap *_gdk_wayland_display_get_keymap (GdkDisplay *display);
|
||||
void _gdk_wayland_keymap_update_keymap (GdkKeymap *gdk_keymap,
|
||||
struct xkb_keymap *xkb_keymap);
|
||||
|
||||
GdkWindow *_gdk_wayland_display_get_selection_owner (GdkDisplay *display,
|
||||
GdkAtom selection);
|
||||
gboolean _gdk_wayland_display_set_selection_owner (GdkDisplay *display,
|
||||
@@ -134,6 +132,8 @@ struct wl_seat *_gdk_wayland_device_get_wl_seat (GdkDevice *device);
|
||||
struct wl_pointer *_gdk_wayland_device_get_wl_pointer (GdkDevice *device);
|
||||
struct wl_keyboard *_gdk_wayland_device_get_wl_keyboard (GdkDevice *device);
|
||||
|
||||
GdkKeymap *_gdk_wayland_device_get_keymap (GdkDevice *device);
|
||||
|
||||
void _gdk_wayland_display_deliver_event (GdkDisplay *display, GdkEvent *event);
|
||||
GSource *_gdk_wayland_display_event_source_new (GdkDisplay *display);
|
||||
void _gdk_wayland_display_queue_events (GdkDisplay *display);
|
||||
|
||||
@@ -77,6 +77,9 @@ struct _GdkWaylandMonitor
|
||||
|
||||
G_DEFINE_TYPE (GdkWaylandScreen, _gdk_wayland_screen, GDK_TYPE_SCREEN)
|
||||
|
||||
#define MM_PER_INCH 25
|
||||
#define DEFAULT_DPI 96
|
||||
|
||||
static void
|
||||
init_monitor_geometry (GdkWaylandMonitor *monitor,
|
||||
int x, int y, int width, int height)
|
||||
@@ -86,8 +89,8 @@ init_monitor_geometry (GdkWaylandMonitor *monitor,
|
||||
monitor->geometry.width = width;
|
||||
monitor->geometry.height = height;
|
||||
|
||||
monitor->width_mm = -1;
|
||||
monitor->height_mm = -1;
|
||||
monitor->width_mm = width/DEFAULT_DPI*MM_PER_INCH;
|
||||
monitor->height_mm = height/DEFAULT_DPI*MM_PER_INCH;
|
||||
monitor->output_name = NULL;
|
||||
monitor->manufacturer = NULL;
|
||||
}
|
||||
@@ -297,6 +300,69 @@ gdk_wayland_screen_get_setting (GdkScreen *screen,
|
||||
const gchar *name,
|
||||
GValue *value)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
|
||||
|
||||
if (strcmp ("gtk-theme-name", name) == 0)
|
||||
{
|
||||
const gchar *s = "Adwaita";
|
||||
GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : %s\n", name, s));
|
||||
g_value_set_string (value, s);
|
||||
return TRUE;
|
||||
}
|
||||
else if (strcmp ("gtk-icon-theme-name", name) == 0)
|
||||
{
|
||||
const gchar *s = "gnome";
|
||||
GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : %s\n", name, s));
|
||||
g_value_set_string (value, s);
|
||||
return TRUE;
|
||||
}
|
||||
else if (strcmp ("gtk-double-click-time", name) == 0)
|
||||
{
|
||||
gint i = 250;
|
||||
GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : %d\n", name, i));
|
||||
g_value_set_int (value, i);
|
||||
return TRUE;
|
||||
}
|
||||
else if (strcmp ("gtk-double-click-distance", name) == 0)
|
||||
{
|
||||
gint i = 5;
|
||||
GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : %d\n", name, i));
|
||||
g_value_set_int (value, i);
|
||||
return TRUE;
|
||||
}
|
||||
else if (strcmp ("gtk-dnd-drag-threshold", name) == 0)
|
||||
{
|
||||
gint i = 8;
|
||||
GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : %d\n", name, i));
|
||||
g_value_set_int (value, i);
|
||||
return TRUE;
|
||||
}
|
||||
else if (strcmp ("gtk-split-cursor", name) == 0)
|
||||
{
|
||||
GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : FALSE\n", name));
|
||||
g_value_set_boolean (value, FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
else if (strcmp ("gtk-alternative-button-order", name) == 0)
|
||||
{
|
||||
GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : TRUE\n", name));
|
||||
g_value_set_boolean (value, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
else if (strcmp ("gtk-alternative-sort-arrows", name) == 0)
|
||||
{
|
||||
GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : TRUE\n", name));
|
||||
g_value_set_boolean (value, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
else if (strcmp ("gtk-xft-dpi", name) == 0)
|
||||
{
|
||||
gint i = 96*1024;
|
||||
GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : TRUE\n", name));
|
||||
g_value_set_int (value, i);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
@@ -633,23 +633,25 @@ gdk_wayland_window_map (GdkWindow *window)
|
||||
{
|
||||
if (impl->transient_for)
|
||||
{
|
||||
struct wl_seat *grab_input_seat = NULL;
|
||||
|
||||
parent = GDK_WINDOW_IMPL_WAYLAND (impl->transient_for->impl);
|
||||
|
||||
if (impl->hint & GDK_WINDOW_TYPE_HINT_POPUP_MENU ||
|
||||
impl->hint & GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU ||
|
||||
impl->hint & GDK_WINDOW_TYPE_HINT_COMBO)
|
||||
/* Use the device that was used for the grab as the device for
|
||||
* the popup window setup - so this relies on GTK+ taking the
|
||||
* grab before showing the popup window.
|
||||
*/
|
||||
if (impl->grab_input_seat)
|
||||
grab_input_seat = impl->grab_input_seat;
|
||||
|
||||
if (!grab_input_seat)
|
||||
grab_input_seat = parent->grab_input_seat;
|
||||
|
||||
if (grab_input_seat &&
|
||||
(impl->hint == GDK_WINDOW_TYPE_HINT_POPUP_MENU ||
|
||||
impl->hint == GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU ||
|
||||
impl->hint == GDK_WINDOW_TYPE_HINT_COMBO))
|
||||
{
|
||||
struct wl_seat *grab_input_seat = NULL;
|
||||
|
||||
/* Use the device that was used for the grab as the device for
|
||||
* the popup window setup - so this relies on GTK+ taking the
|
||||
* grab before showing the popup window.
|
||||
*/
|
||||
if (impl->grab_input_seat)
|
||||
grab_input_seat = impl->grab_input_seat;
|
||||
|
||||
if (!grab_input_seat)
|
||||
grab_input_seat = parent->grab_input_seat;
|
||||
|
||||
wl_shell_surface_set_popup (impl->shell_surface,
|
||||
grab_input_seat,
|
||||
|
||||
@@ -3326,7 +3326,7 @@ gdk_event_prepare (GSource *source,
|
||||
{
|
||||
gboolean retval;
|
||||
|
||||
GDK_THREADS_ENTER ();
|
||||
gdk_threads_enter ();
|
||||
|
||||
*timeout = -1;
|
||||
|
||||
@@ -3334,7 +3334,7 @@ gdk_event_prepare (GSource *source,
|
||||
(modal_win32_dialog == NULL &&
|
||||
GetQueueStatus (QS_ALLINPUT) != 0));
|
||||
|
||||
GDK_THREADS_LEAVE ();
|
||||
gdk_threads_leave ();
|
||||
|
||||
return retval;
|
||||
}
|
||||
@@ -3344,7 +3344,7 @@ gdk_event_check (GSource *source)
|
||||
{
|
||||
gboolean retval;
|
||||
|
||||
GDK_THREADS_ENTER ();
|
||||
gdk_threads_enter ();
|
||||
|
||||
if (event_poll_fd.revents & G_IO_IN)
|
||||
{
|
||||
@@ -3357,7 +3357,7 @@ gdk_event_check (GSource *source)
|
||||
retval = FALSE;
|
||||
}
|
||||
|
||||
GDK_THREADS_LEAVE ();
|
||||
gdk_threads_leave ();
|
||||
|
||||
return retval;
|
||||
}
|
||||
@@ -3369,7 +3369,7 @@ gdk_event_dispatch (GSource *source,
|
||||
{
|
||||
GdkEvent *event;
|
||||
|
||||
GDK_THREADS_ENTER ();
|
||||
gdk_threads_enter ();
|
||||
|
||||
_gdk_win32_display_queue_events (_gdk_display);
|
||||
event = _gdk_event_unqueue (_gdk_display);
|
||||
@@ -3389,7 +3389,7 @@ gdk_event_dispatch (GSource *source,
|
||||
}
|
||||
}
|
||||
|
||||
GDK_THREADS_LEAVE ();
|
||||
gdk_threads_leave ();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1483,11 +1483,11 @@ process_internal_connection (GIOChannel *gioc,
|
||||
{
|
||||
GdkInternalConnection *connection = (GdkInternalConnection *)data;
|
||||
|
||||
GDK_THREADS_ENTER ();
|
||||
gdk_threads_enter ();
|
||||
|
||||
XProcessInternalConnection ((Display*)connection->display, connection->fd);
|
||||
|
||||
GDK_THREADS_LEAVE ();
|
||||
gdk_threads_leave ();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -273,13 +273,13 @@ gdk_event_source_prepare (GSource *source,
|
||||
GdkDisplay *display = ((GdkEventSource*) source)->display;
|
||||
gboolean retval;
|
||||
|
||||
GDK_THREADS_ENTER ();
|
||||
gdk_threads_enter ();
|
||||
|
||||
*timeout = -1;
|
||||
retval = (_gdk_event_queue_find_first (display) != NULL ||
|
||||
gdk_check_xpending (display));
|
||||
|
||||
GDK_THREADS_LEAVE ();
|
||||
gdk_threads_leave ();
|
||||
|
||||
return retval;
|
||||
}
|
||||
@@ -290,7 +290,7 @@ gdk_event_source_check (GSource *source)
|
||||
GdkEventSource *event_source = (GdkEventSource*) source;
|
||||
gboolean retval;
|
||||
|
||||
GDK_THREADS_ENTER ();
|
||||
gdk_threads_enter ();
|
||||
|
||||
if (event_source->event_poll_fd.revents & G_IO_IN)
|
||||
retval = (_gdk_event_queue_find_first (event_source->display) != NULL ||
|
||||
@@ -298,7 +298,7 @@ gdk_event_source_check (GSource *source)
|
||||
else
|
||||
retval = FALSE;
|
||||
|
||||
GDK_THREADS_LEAVE ();
|
||||
gdk_threads_leave ();
|
||||
|
||||
return retval;
|
||||
}
|
||||
@@ -349,7 +349,7 @@ gdk_event_source_dispatch (GSource *source,
|
||||
GdkDisplay *display = ((GdkEventSource*) source)->display;
|
||||
GdkEvent *event;
|
||||
|
||||
GDK_THREADS_ENTER ();
|
||||
gdk_threads_enter ();
|
||||
|
||||
event = gdk_display_get_event (display);
|
||||
|
||||
@@ -360,7 +360,7 @@ gdk_event_source_dispatch (GSource *source,
|
||||
gdk_event_free (event);
|
||||
}
|
||||
|
||||
GDK_THREADS_LEAVE ();
|
||||
gdk_threads_leave ();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -394,19 +394,20 @@ gtk_appchooser_impl_c_sources = \
|
||||
gtkappchooseronlinepk.c
|
||||
endif
|
||||
|
||||
gtk_private_type_h_sources = \
|
||||
gtkcsstypesprivate.h
|
||||
gtk_private_type_h_sources = \
|
||||
gtkcsstypesprivate.h \
|
||||
gtktexthandleprivate.h
|
||||
|
||||
|
||||
# GTK+ header files that don't get installed
|
||||
gtk_private_h_sources = \
|
||||
gactionmuxer.h \
|
||||
gsimpleactionobserver.h \
|
||||
gactionobserver.h \
|
||||
gactionobservable.h \
|
||||
gtkapplicationprivate.h \
|
||||
gtkaccelgroupprivate.h \
|
||||
gtkaccelmapprivate.h \
|
||||
gtkactionhelper.h \
|
||||
gtkallocatedbitmaskprivate.h \
|
||||
gtkappchooserprivate.h \
|
||||
gtkappchoosermodule.h \
|
||||
@@ -525,6 +526,7 @@ gtk_private_h_sources = \
|
||||
gtktextbtree.h \
|
||||
gtktextbufferserialize.h \
|
||||
gtktextchildprivate.h \
|
||||
gtktexthandleprivate.h \
|
||||
gtktextiterprivate.h \
|
||||
gtktextmarkprivate.h \
|
||||
gtktextsegment.h \
|
||||
@@ -571,7 +573,6 @@ deprecated_c_sources = \
|
||||
gtk_base_c_sources = \
|
||||
$(deprecated_c_sources) \
|
||||
gactionmuxer.c \
|
||||
gsimpleactionobserver.c \
|
||||
gactionobserver.c \
|
||||
gactionobservable.c \
|
||||
gtkactionable.c \
|
||||
@@ -586,6 +587,7 @@ gtk_base_c_sources = \
|
||||
gtkaccelmap.c \
|
||||
gtkaccessible.c \
|
||||
gtkaction.c \
|
||||
gtkactionhelper.c \
|
||||
gtkactiongroup.c \
|
||||
gtkactivatable.c \
|
||||
gtkadjustment.c \
|
||||
@@ -821,6 +823,7 @@ gtk_base_c_sources = \
|
||||
gtktextbufferserialize.c \
|
||||
gtktextchild.c \
|
||||
gtktextdisplay.c \
|
||||
gtktexthandle.c \
|
||||
gtktextiter.c \
|
||||
gtktextlayout.c \
|
||||
gtktextmark.c \
|
||||
|
||||
@@ -26,13 +26,13 @@ G_DEFINE_TYPE (GailMisc, _gail_misc, ATK_TYPE_MISC)
|
||||
static void
|
||||
gail_misc_threads_enter (AtkMisc *misc)
|
||||
{
|
||||
GDK_THREADS_ENTER ();
|
||||
gdk_threads_enter ();
|
||||
}
|
||||
|
||||
static void
|
||||
gail_misc_threads_leave (AtkMisc *misc)
|
||||
{
|
||||
GDK_THREADS_LEAVE ();
|
||||
gdk_threads_leave ();
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include "gtkpango.h"
|
||||
#include "gtkentryaccessible.h"
|
||||
#include "gtkentryprivate.h"
|
||||
#include "gtkcomboboxaccessible.h"
|
||||
|
||||
/* Callbacks */
|
||||
@@ -213,22 +214,12 @@ gtk_entry_accessible_get_text (AtkText *atk_text,
|
||||
gint end_pos)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
const gchar *text;
|
||||
|
||||
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
|
||||
if (widget == NULL)
|
||||
return NULL;
|
||||
|
||||
/* FIXME: is this acceptable ? */
|
||||
if (!gtk_entry_get_visibility (GTK_ENTRY (widget)))
|
||||
return g_strdup ("");
|
||||
|
||||
text = gtk_entry_get_text (GTK_ENTRY (widget));
|
||||
|
||||
if (text)
|
||||
return g_utf8_substring (text, start_pos, end_pos > -1 ? end_pos : g_utf8_strlen (text, -1));
|
||||
|
||||
return NULL;
|
||||
return _gtk_entry_get_display_text (GTK_ENTRY (widget), start_pos, end_pos);
|
||||
}
|
||||
|
||||
static gchar *
|
||||
@@ -244,10 +235,6 @@ gtk_entry_accessible_get_text_before_offset (AtkText *text,
|
||||
if (widget == NULL)
|
||||
return NULL;
|
||||
|
||||
/* FIXME: is this acceptable ? */
|
||||
if (!gtk_entry_get_visibility (GTK_ENTRY (widget)))
|
||||
return g_strdup ("");
|
||||
|
||||
return _gtk_pango_get_text_before (gtk_entry_get_layout (GTK_ENTRY (widget)),
|
||||
boundary_type, offset,
|
||||
start_offset, end_offset);
|
||||
@@ -266,10 +253,6 @@ gtk_entry_accessible_get_text_at_offset (AtkText *text,
|
||||
if (widget == NULL)
|
||||
return NULL;
|
||||
|
||||
/* FIXME: is this acceptable ? */
|
||||
if (!gtk_entry_get_visibility (GTK_ENTRY (widget)))
|
||||
return g_strdup ("");
|
||||
|
||||
return _gtk_pango_get_text_at (gtk_entry_get_layout (GTK_ENTRY (widget)),
|
||||
boundary_type, offset,
|
||||
start_offset, end_offset);
|
||||
@@ -288,10 +271,6 @@ gtk_entry_accessible_get_text_after_offset (AtkText *text,
|
||||
if (widget == NULL)
|
||||
return NULL;
|
||||
|
||||
/* FIXME: is this acceptable ? */
|
||||
if (!gtk_entry_get_visibility (GTK_ENTRY (widget)))
|
||||
return g_strdup ("");
|
||||
|
||||
return _gtk_pango_get_text_after (gtk_entry_get_layout (GTK_ENTRY (widget)),
|
||||
boundary_type, offset,
|
||||
start_offset, end_offset);
|
||||
@@ -301,18 +280,23 @@ static gint
|
||||
gtk_entry_accessible_get_character_count (AtkText *atk_text)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
const gchar *text;
|
||||
gchar *text;
|
||||
glong char_count;
|
||||
|
||||
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
|
||||
if (widget == NULL)
|
||||
return 0;
|
||||
|
||||
text = gtk_entry_get_text (GTK_ENTRY (widget));
|
||||
text = _gtk_entry_get_display_text (GTK_ENTRY (widget), 0, -1);
|
||||
|
||||
char_count = 0;
|
||||
if (text)
|
||||
return g_utf8_strlen (text, -1);
|
||||
{
|
||||
char_count = g_utf8_strlen (text, -1);
|
||||
g_free (text);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return char_count;
|
||||
}
|
||||
|
||||
static gint
|
||||
@@ -415,7 +399,7 @@ gtk_entry_accessible_get_character_extents (AtkText *text,
|
||||
GtkWidget *widget;
|
||||
GtkEntry *entry;
|
||||
PangoRectangle char_rect;
|
||||
const gchar *entry_text;
|
||||
gchar *entry_text;
|
||||
gint index, x_layout, y_layout;
|
||||
GdkWindow *window;
|
||||
gint x_window, y_window;
|
||||
@@ -427,8 +411,10 @@ gtk_entry_accessible_get_character_extents (AtkText *text,
|
||||
entry = GTK_ENTRY (widget);
|
||||
|
||||
gtk_entry_get_layout_offsets (entry, &x_layout, &y_layout);
|
||||
entry_text = gtk_entry_get_text (entry);
|
||||
entry_text = _gtk_entry_get_display_text (entry, 0, -1);
|
||||
index = g_utf8_offset_to_pointer (entry_text, offset) - entry_text;
|
||||
g_free (entry_text);
|
||||
|
||||
pango_layout_index_to_pos (gtk_entry_get_layout (entry), index, &char_rect);
|
||||
pango_extents_to_pixels (&char_rect, NULL);
|
||||
|
||||
@@ -458,11 +444,12 @@ gtk_entry_accessible_get_offset_at_point (AtkText *atk_text,
|
||||
{
|
||||
GtkWidget *widget;
|
||||
GtkEntry *entry;
|
||||
const gchar *text;
|
||||
gchar *text;
|
||||
gint index, x_layout, y_layout;
|
||||
gint x_window, y_window;
|
||||
gint x_local, y_local;
|
||||
GdkWindow *window;
|
||||
glong offset;
|
||||
|
||||
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
|
||||
if (widget == NULL)
|
||||
@@ -497,13 +484,15 @@ gtk_entry_accessible_get_offset_at_point (AtkText *atk_text,
|
||||
index = -1;
|
||||
}
|
||||
|
||||
offset = -1;
|
||||
if (index != -1)
|
||||
{
|
||||
text = gtk_entry_get_text (entry);
|
||||
return g_utf8_pointer_to_offset (text, text + index);
|
||||
text = _gtk_entry_get_display_text (entry, 0, -1);
|
||||
offset = g_utf8_pointer_to_offset (text, text + index);
|
||||
g_free (text);
|
||||
}
|
||||
|
||||
return -1;
|
||||
return offset;
|
||||
}
|
||||
|
||||
static gint
|
||||
@@ -620,23 +609,28 @@ gtk_entry_accessible_get_character_at_offset (AtkText *atk_text,
|
||||
gint offset)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
const gchar *text;
|
||||
gchar *text;
|
||||
gchar *index;
|
||||
gunichar result;
|
||||
|
||||
result = '\0';
|
||||
|
||||
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
|
||||
if (widget == NULL)
|
||||
return '\0';
|
||||
return result;
|
||||
|
||||
if (!gtk_entry_get_visibility (GTK_ENTRY (widget)))
|
||||
return '\0';
|
||||
return result;
|
||||
|
||||
text = gtk_entry_get_text (GTK_ENTRY (widget));
|
||||
if (offset >= g_utf8_strlen (text, -1))
|
||||
return '\0';
|
||||
text = _gtk_entry_get_display_text (GTK_ENTRY (widget), 0, -1);
|
||||
if (offset < g_utf8_strlen (text, -1))
|
||||
{
|
||||
index = g_utf8_offset_to_pointer (text, offset);
|
||||
result = g_utf8_get_char (index);
|
||||
g_free (text);
|
||||
}
|
||||
|
||||
index = g_utf8_offset_to_pointer (text, offset);
|
||||
|
||||
return g_utf8_get_char (index);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -870,10 +864,11 @@ delete_text_cb (GtkEditable *editable,
|
||||
|
||||
if (end < 0)
|
||||
{
|
||||
const gchar *text;
|
||||
gchar *text;
|
||||
|
||||
text = gtk_entry_get_text (GTK_ENTRY (editable));
|
||||
text = _gtk_entry_get_display_text (GTK_ENTRY (editable), 0, -1);
|
||||
end = g_utf8_strlen (text, -1);
|
||||
g_free (text);
|
||||
}
|
||||
|
||||
if (end == start)
|
||||
|
||||
@@ -63,14 +63,24 @@ struct _GActionMuxer
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GHashTable *actions;
|
||||
GHashTable *observed_actions;
|
||||
GHashTable *groups;
|
||||
GActionMuxer *parent;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GActionMuxer, g_action_muxer, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_GROUP, g_action_muxer_group_iface_init)
|
||||
G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_OBSERVABLE, g_action_muxer_observable_iface_init))
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_PARENT,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *properties[NUM_PROPERTIES];
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GActionMuxer *muxer;
|
||||
@@ -86,147 +96,243 @@ typedef struct
|
||||
gulong handler_ids[4];
|
||||
} Group;
|
||||
|
||||
static void
|
||||
g_action_muxer_append_group_actions (gpointer key,
|
||||
gpointer value,
|
||||
gpointer user_data)
|
||||
{
|
||||
const gchar *prefix = key;
|
||||
Group *group = value;
|
||||
GArray *actions = user_data;
|
||||
gchar **group_actions;
|
||||
gchar **action;
|
||||
|
||||
group_actions = g_action_group_list_actions (group->group);
|
||||
for (action = group_actions; *action; action++)
|
||||
{
|
||||
gchar *fullname;
|
||||
|
||||
fullname = g_strconcat (prefix, ".", *action, NULL);
|
||||
g_array_append_val (actions, fullname);
|
||||
}
|
||||
|
||||
g_strfreev (group_actions);
|
||||
}
|
||||
|
||||
static gchar **
|
||||
g_action_muxer_list_actions (GActionGroup *action_group)
|
||||
{
|
||||
GActionMuxer *muxer = G_ACTION_MUXER (action_group);
|
||||
GHashTableIter iter;
|
||||
gchar *key;
|
||||
gchar **keys;
|
||||
gsize i;
|
||||
GArray *actions;
|
||||
|
||||
keys = g_new (gchar *, g_hash_table_size (muxer->actions) + 1);
|
||||
actions = g_array_new (TRUE, FALSE, sizeof (gchar *));
|
||||
|
||||
i = 0;
|
||||
g_hash_table_iter_init (&iter, muxer->actions);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *) &key, NULL))
|
||||
keys[i++] = g_strdup (key);
|
||||
keys[i] = NULL;
|
||||
for ( ; muxer != NULL; muxer = muxer->parent)
|
||||
{
|
||||
g_hash_table_foreach (muxer->groups,
|
||||
g_action_muxer_append_group_actions,
|
||||
actions);
|
||||
}
|
||||
|
||||
return keys;
|
||||
return (gchar **) g_array_free (actions, FALSE);
|
||||
}
|
||||
|
||||
static Group *
|
||||
g_action_muxer_find_group (GActionMuxer *muxer,
|
||||
const gchar **name)
|
||||
const gchar *full_name,
|
||||
const gchar **action_name)
|
||||
{
|
||||
const gchar *dot;
|
||||
gchar *prefix;
|
||||
Group *group;
|
||||
|
||||
dot = strchr (*name, '.');
|
||||
dot = strchr (full_name, '.');
|
||||
|
||||
if (!dot)
|
||||
return NULL;
|
||||
|
||||
prefix = g_strndup (*name, dot - *name);
|
||||
prefix = g_strndup (full_name, dot - full_name);
|
||||
group = g_hash_table_lookup (muxer->groups, prefix);
|
||||
g_free (prefix);
|
||||
|
||||
*name = dot + 1;
|
||||
if (action_name)
|
||||
*action_name = dot + 1;
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
static Action *
|
||||
g_action_muxer_lookup_action (GActionMuxer *muxer,
|
||||
const gchar *prefix,
|
||||
const gchar *action_name,
|
||||
gchar **fullname)
|
||||
{
|
||||
Action *action;
|
||||
|
||||
*fullname = g_strconcat (prefix, ".", action_name, NULL);
|
||||
action = g_hash_table_lookup (muxer->actions, *fullname);
|
||||
|
||||
return action;
|
||||
}
|
||||
|
||||
static void
|
||||
g_action_muxer_action_enabled_changed (GActionGroup *action_group,
|
||||
g_action_muxer_action_enabled_changed (GActionMuxer *muxer,
|
||||
const gchar *action_name,
|
||||
gboolean enabled,
|
||||
gpointer user_data)
|
||||
gboolean enabled)
|
||||
{
|
||||
Group *group = user_data;
|
||||
gchar *fullname;
|
||||
Action *action;
|
||||
GSList *node;
|
||||
|
||||
action = g_action_muxer_lookup_action (group->muxer, group->prefix, action_name, &fullname);
|
||||
action = g_hash_table_lookup (muxer->observed_actions, action_name);
|
||||
for (node = action ? action->watchers : NULL; node; node = node->next)
|
||||
g_action_observer_action_enabled_changed (node->data, G_ACTION_OBSERVABLE (group->muxer), fullname, enabled);
|
||||
g_action_group_action_enabled_changed (G_ACTION_GROUP (group->muxer), fullname, enabled);
|
||||
g_action_observer_action_enabled_changed (node->data, G_ACTION_OBSERVABLE (muxer), action_name, enabled);
|
||||
g_action_group_action_enabled_changed (G_ACTION_GROUP (muxer), action_name, enabled);
|
||||
}
|
||||
|
||||
static void
|
||||
g_action_muxer_group_action_enabled_changed (GActionGroup *action_group,
|
||||
const gchar *action_name,
|
||||
gboolean enabled,
|
||||
gpointer user_data)
|
||||
{
|
||||
Group *group = user_data;
|
||||
gchar *fullname;
|
||||
|
||||
fullname = g_strconcat (group->prefix, ".", action_name, NULL);
|
||||
g_action_muxer_action_enabled_changed (group->muxer, fullname, enabled);
|
||||
|
||||
g_free (fullname);
|
||||
}
|
||||
|
||||
static void
|
||||
g_action_muxer_action_state_changed (GActionGroup *action_group,
|
||||
g_action_muxer_parent_action_enabled_changed (GActionGroup *action_group,
|
||||
const gchar *action_name,
|
||||
gboolean enabled,
|
||||
gpointer user_data)
|
||||
{
|
||||
GActionMuxer *muxer = user_data;
|
||||
|
||||
g_action_muxer_action_enabled_changed (muxer, action_name, enabled);
|
||||
}
|
||||
|
||||
static void
|
||||
g_action_muxer_action_state_changed (GActionMuxer *muxer,
|
||||
const gchar *action_name,
|
||||
GVariant *state,
|
||||
gpointer user_data)
|
||||
GVariant *state)
|
||||
{
|
||||
Group *group = user_data;
|
||||
gchar *fullname;
|
||||
Action *action;
|
||||
GSList *node;
|
||||
|
||||
action = g_action_muxer_lookup_action (group->muxer, group->prefix, action_name, &fullname);
|
||||
action = g_hash_table_lookup (muxer->observed_actions, action_name);
|
||||
for (node = action ? action->watchers : NULL; node; node = node->next)
|
||||
g_action_observer_action_state_changed (node->data, G_ACTION_OBSERVABLE (group->muxer), fullname, state);
|
||||
g_action_group_action_state_changed (G_ACTION_GROUP (group->muxer), fullname, state);
|
||||
g_action_observer_action_state_changed (node->data, G_ACTION_OBSERVABLE (muxer), action_name, state);
|
||||
g_action_group_action_state_changed (G_ACTION_GROUP (muxer), action_name, state);
|
||||
}
|
||||
|
||||
static void
|
||||
g_action_muxer_group_action_state_changed (GActionGroup *action_group,
|
||||
const gchar *action_name,
|
||||
GVariant *state,
|
||||
gpointer user_data)
|
||||
{
|
||||
Group *group = user_data;
|
||||
gchar *fullname;
|
||||
|
||||
fullname = g_strconcat (group->prefix, ".", action_name, NULL);
|
||||
g_action_muxer_action_state_changed (group->muxer, fullname, state);
|
||||
|
||||
g_free (fullname);
|
||||
}
|
||||
|
||||
static void
|
||||
g_action_muxer_action_added (GActionGroup *action_group,
|
||||
g_action_muxer_parent_action_state_changed (GActionGroup *action_group,
|
||||
const gchar *action_name,
|
||||
GVariant *state,
|
||||
gpointer user_data)
|
||||
{
|
||||
GActionMuxer *muxer = user_data;
|
||||
|
||||
g_action_muxer_action_state_changed (muxer, action_name, state);
|
||||
}
|
||||
|
||||
static void
|
||||
g_action_muxer_action_added (GActionMuxer *muxer,
|
||||
const gchar *action_name,
|
||||
gpointer user_data)
|
||||
GActionGroup *original_group,
|
||||
const gchar *orignal_action_name)
|
||||
{
|
||||
const GVariantType *parameter_type;
|
||||
Group *group = user_data;
|
||||
gboolean enabled;
|
||||
GVariant *state;
|
||||
Action *action;
|
||||
|
||||
if (g_action_group_query_action (group->group, action_name, &enabled, ¶meter_type, NULL, NULL, &state))
|
||||
action = g_hash_table_lookup (muxer->observed_actions, action_name);
|
||||
|
||||
if (action && action->watchers &&
|
||||
g_action_group_query_action (original_group, orignal_action_name,
|
||||
&enabled, ¶meter_type, NULL, NULL, &state))
|
||||
{
|
||||
gchar *fullname;
|
||||
Action *action;
|
||||
GSList *node;
|
||||
|
||||
action = g_action_muxer_lookup_action (group->muxer, group->prefix, action_name, &fullname);
|
||||
|
||||
for (node = action ? action->watchers : NULL; node; node = node->next)
|
||||
for (node = action->watchers; node; node = node->next)
|
||||
g_action_observer_action_added (node->data,
|
||||
G_ACTION_OBSERVABLE (group->muxer),
|
||||
fullname, parameter_type, enabled, state);
|
||||
|
||||
g_action_group_action_added (G_ACTION_GROUP (group->muxer), fullname);
|
||||
G_ACTION_OBSERVABLE (muxer),
|
||||
action_name, parameter_type, enabled, state);
|
||||
|
||||
if (state)
|
||||
g_variant_unref (state);
|
||||
|
||||
g_free (fullname);
|
||||
}
|
||||
|
||||
g_action_group_action_added (G_ACTION_GROUP (muxer), action_name);
|
||||
}
|
||||
|
||||
static void
|
||||
g_action_muxer_action_removed (GActionGroup *action_group,
|
||||
const gchar *action_name,
|
||||
gpointer user_data)
|
||||
g_action_muxer_action_added_to_group (GActionGroup *action_group,
|
||||
const gchar *action_name,
|
||||
gpointer user_data)
|
||||
{
|
||||
Group *group = user_data;
|
||||
gchar *fullname;
|
||||
|
||||
fullname = g_strconcat (group->prefix, ".", action_name, NULL);
|
||||
g_action_muxer_action_added (group->muxer, fullname, action_group, action_name);
|
||||
|
||||
g_free (fullname);
|
||||
}
|
||||
|
||||
static void
|
||||
g_action_muxer_action_added_to_parent (GActionGroup *action_group,
|
||||
const gchar *action_name,
|
||||
gpointer user_data)
|
||||
{
|
||||
GActionMuxer *muxer = user_data;
|
||||
|
||||
g_action_muxer_action_added (muxer, action_name, action_group, action_name);
|
||||
}
|
||||
|
||||
static void
|
||||
g_action_muxer_action_removed (GActionMuxer *muxer,
|
||||
const gchar *action_name)
|
||||
{
|
||||
Action *action;
|
||||
GSList *node;
|
||||
|
||||
action = g_action_muxer_lookup_action (group->muxer, group->prefix, action_name, &fullname);
|
||||
action = g_hash_table_lookup (muxer->observed_actions, action_name);
|
||||
for (node = action ? action->watchers : NULL; node; node = node->next)
|
||||
g_action_observer_action_removed (node->data, G_ACTION_OBSERVABLE (group->muxer), fullname);
|
||||
g_action_group_action_removed (G_ACTION_GROUP (group->muxer), fullname);
|
||||
g_action_observer_action_removed (node->data, G_ACTION_OBSERVABLE (muxer), action_name);
|
||||
g_action_group_action_removed (G_ACTION_GROUP (muxer), action_name);
|
||||
}
|
||||
|
||||
static void
|
||||
g_action_muxer_action_removed_from_group (GActionGroup *action_group,
|
||||
const gchar *action_name,
|
||||
gpointer user_data)
|
||||
{
|
||||
Group *group = user_data;
|
||||
gchar *fullname;
|
||||
|
||||
fullname = g_strconcat (group->prefix, ".", action_name, NULL);
|
||||
g_action_muxer_action_removed (group->muxer, fullname);
|
||||
|
||||
g_free (fullname);
|
||||
}
|
||||
|
||||
static void
|
||||
g_action_muxer_action_removed_from_parent (GActionGroup *action_group,
|
||||
const gchar *action_name,
|
||||
gpointer user_data)
|
||||
{
|
||||
GActionMuxer *muxer = user_data;
|
||||
|
||||
g_action_muxer_action_removed (muxer, action_name);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
g_action_muxer_query_action (GActionGroup *action_group,
|
||||
const gchar *action_name,
|
||||
@@ -238,14 +344,20 @@ g_action_muxer_query_action (GActionGroup *action_group,
|
||||
{
|
||||
GActionMuxer *muxer = G_ACTION_MUXER (action_group);
|
||||
Group *group;
|
||||
const gchar *unprefixed_name;
|
||||
|
||||
group = g_action_muxer_find_group (muxer, &action_name);
|
||||
group = g_action_muxer_find_group (muxer, action_name, &unprefixed_name);
|
||||
|
||||
if (!group)
|
||||
return FALSE;
|
||||
if (group)
|
||||
return g_action_group_query_action (group->group, unprefixed_name, enabled,
|
||||
parameter_type, state_type, state_hint, state);
|
||||
|
||||
return g_action_group_query_action (group->group, action_name, enabled,
|
||||
parameter_type, state_type, state_hint, state);
|
||||
if (muxer->parent)
|
||||
return g_action_group_query_action (G_ACTION_GROUP (muxer->parent), action_name,
|
||||
enabled, parameter_type,
|
||||
state_type, state_hint, state);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -255,11 +367,14 @@ g_action_muxer_activate_action (GActionGroup *action_group,
|
||||
{
|
||||
GActionMuxer *muxer = G_ACTION_MUXER (action_group);
|
||||
Group *group;
|
||||
const gchar *unprefixed_name;
|
||||
|
||||
group = g_action_muxer_find_group (muxer, &action_name);
|
||||
group = g_action_muxer_find_group (muxer, action_name, &unprefixed_name);
|
||||
|
||||
if (group)
|
||||
g_action_group_activate_action (group->group, action_name, parameter);
|
||||
g_action_group_activate_action (group->group, unprefixed_name, parameter);
|
||||
else if (muxer->parent)
|
||||
g_action_group_activate_action (G_ACTION_GROUP (muxer->parent), action_name, parameter);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -269,11 +384,14 @@ g_action_muxer_change_action_state (GActionGroup *action_group,
|
||||
{
|
||||
GActionMuxer *muxer = G_ACTION_MUXER (action_group);
|
||||
Group *group;
|
||||
const gchar *unprefixed_name;
|
||||
|
||||
group = g_action_muxer_find_group (muxer, &action_name);
|
||||
group = g_action_muxer_find_group (muxer, action_name, &unprefixed_name);
|
||||
|
||||
if (group)
|
||||
g_action_group_change_action_state (group->group, action_name, state);
|
||||
g_action_group_change_action_state (group->group, unprefixed_name, state);
|
||||
else if (muxer->parent)
|
||||
g_action_group_change_action_state (G_ACTION_GROUP (muxer->parent), action_name, state);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -289,14 +407,7 @@ g_action_muxer_unregister_internal (Action *action,
|
||||
*ptr = g_slist_remove (*ptr, observer);
|
||||
|
||||
if (action->watchers == NULL)
|
||||
{
|
||||
g_hash_table_remove (muxer->actions, action->fullname);
|
||||
g_free (action->fullname);
|
||||
|
||||
g_slice_free (Action, action);
|
||||
|
||||
g_object_unref (muxer);
|
||||
}
|
||||
g_hash_table_remove (muxer->observed_actions, action->fullname);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -319,16 +430,16 @@ g_action_muxer_register_observer (GActionObservable *observable,
|
||||
GActionMuxer *muxer = G_ACTION_MUXER (observable);
|
||||
Action *action;
|
||||
|
||||
action = g_hash_table_lookup (muxer->actions, name);
|
||||
action = g_hash_table_lookup (muxer->observed_actions, name);
|
||||
|
||||
if (action == NULL)
|
||||
{
|
||||
action = g_slice_new (Action);
|
||||
action->muxer = g_object_ref (muxer);
|
||||
action->muxer = muxer;
|
||||
action->fullname = g_strdup (name);
|
||||
action->watchers = NULL;
|
||||
|
||||
g_hash_table_insert (muxer->actions, action->fullname, action);
|
||||
g_hash_table_insert (muxer->observed_actions, action->fullname, action);
|
||||
}
|
||||
|
||||
action->watchers = g_slist_prepend (action->watchers, observer);
|
||||
@@ -343,7 +454,7 @@ g_action_muxer_unregister_observer (GActionObservable *observable,
|
||||
GActionMuxer *muxer = G_ACTION_MUXER (observable);
|
||||
Action *action;
|
||||
|
||||
action = g_hash_table_lookup (muxer->actions, name);
|
||||
action = g_hash_table_lookup (muxer->observed_actions, name);
|
||||
g_object_weak_unref (G_OBJECT (observer), g_action_muxer_weak_notify, action);
|
||||
g_action_muxer_unregister_internal (action, observer);
|
||||
}
|
||||
@@ -364,23 +475,97 @@ g_action_muxer_free_group (gpointer data)
|
||||
g_slice_free (Group, group);
|
||||
}
|
||||
|
||||
static void
|
||||
g_action_muxer_free_action (gpointer data)
|
||||
{
|
||||
Action *action = data;
|
||||
GSList *it;
|
||||
|
||||
for (it = action->watchers; it; it = it->next)
|
||||
g_object_weak_unref (G_OBJECT (it->data), g_action_muxer_weak_notify, action);
|
||||
|
||||
g_slist_free (action->watchers);
|
||||
g_free (action->fullname);
|
||||
|
||||
g_slice_free (Action, action);
|
||||
}
|
||||
|
||||
static void
|
||||
g_action_muxer_finalize (GObject *object)
|
||||
{
|
||||
GActionMuxer *muxer = G_ACTION_MUXER (object);
|
||||
|
||||
g_assert_cmpint (g_hash_table_size (muxer->actions), ==, 0);
|
||||
g_hash_table_unref (muxer->actions);
|
||||
g_assert_cmpint (g_hash_table_size (muxer->observed_actions), ==, 0);
|
||||
g_hash_table_unref (muxer->observed_actions);
|
||||
g_hash_table_unref (muxer->groups);
|
||||
|
||||
G_OBJECT_CLASS (g_action_muxer_parent_class)
|
||||
->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
g_action_muxer_dispose (GObject *object)
|
||||
{
|
||||
GActionMuxer *muxer = G_ACTION_MUXER (object);
|
||||
|
||||
if (muxer->parent)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (muxer->parent, g_action_muxer_action_added_to_parent, muxer);
|
||||
g_signal_handlers_disconnect_by_func (muxer->parent, g_action_muxer_action_removed_from_parent, muxer);
|
||||
g_signal_handlers_disconnect_by_func (muxer->parent, g_action_muxer_parent_action_enabled_changed, muxer);
|
||||
g_signal_handlers_disconnect_by_func (muxer->parent, g_action_muxer_parent_action_state_changed, muxer);
|
||||
|
||||
g_clear_object (&muxer->parent);
|
||||
}
|
||||
|
||||
g_hash_table_remove_all (muxer->observed_actions);
|
||||
|
||||
G_OBJECT_CLASS (g_action_muxer_parent_class)
|
||||
->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
g_action_muxer_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GActionMuxer *muxer = G_ACTION_MUXER (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_PARENT:
|
||||
g_value_set_object (value, g_action_muxer_get_parent (muxer));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
g_action_muxer_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GActionMuxer *muxer = G_ACTION_MUXER (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_PARENT:
|
||||
g_action_muxer_set_parent (muxer, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
g_action_muxer_init (GActionMuxer *muxer)
|
||||
{
|
||||
muxer->actions = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
muxer->observed_actions = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_action_muxer_free_action);
|
||||
muxer->groups = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_action_muxer_free_group);
|
||||
}
|
||||
|
||||
@@ -403,7 +588,18 @@ g_action_muxer_group_iface_init (GActionGroupInterface *iface)
|
||||
static void
|
||||
g_action_muxer_class_init (GObjectClass *class)
|
||||
{
|
||||
class->get_property = g_action_muxer_get_property;
|
||||
class->set_property = g_action_muxer_set_property;
|
||||
class->finalize = g_action_muxer_finalize;
|
||||
class->dispose = g_action_muxer_dispose;
|
||||
|
||||
properties[PROP_PARENT] = g_param_spec_object ("parent", "Parent",
|
||||
"The parent muxer",
|
||||
G_TYPE_ACTION_MUXER,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (class, NUM_PROPERTIES, properties);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -447,17 +643,17 @@ g_action_muxer_insert (GActionMuxer *muxer,
|
||||
|
||||
actions = g_action_group_list_actions (group->group);
|
||||
for (i = 0; actions[i]; i++)
|
||||
g_action_muxer_action_added (group->group, actions[i], group);
|
||||
g_action_muxer_action_added_to_group (group->group, actions[i], group);
|
||||
g_strfreev (actions);
|
||||
|
||||
group->handler_ids[0] = g_signal_connect (group->group, "action-added",
|
||||
G_CALLBACK (g_action_muxer_action_added), group);
|
||||
G_CALLBACK (g_action_muxer_action_added_to_group), group);
|
||||
group->handler_ids[1] = g_signal_connect (group->group, "action-removed",
|
||||
G_CALLBACK (g_action_muxer_action_removed), group);
|
||||
G_CALLBACK (g_action_muxer_action_removed_from_group), group);
|
||||
group->handler_ids[2] = g_signal_connect (group->group, "action-enabled-changed",
|
||||
G_CALLBACK (g_action_muxer_action_enabled_changed), group);
|
||||
G_CALLBACK (g_action_muxer_group_action_enabled_changed), group);
|
||||
group->handler_ids[3] = g_signal_connect (group->group, "action-state-changed",
|
||||
G_CALLBACK (g_action_muxer_action_state_changed), group);
|
||||
G_CALLBACK (g_action_muxer_group_action_state_changed), group);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -487,7 +683,7 @@ g_action_muxer_remove (GActionMuxer *muxer,
|
||||
|
||||
actions = g_action_group_list_actions (group->group);
|
||||
for (i = 0; actions[i]; i++)
|
||||
g_action_muxer_action_removed (group->group, actions[i], group);
|
||||
g_action_muxer_action_removed_from_group (group->group, actions[i], group);
|
||||
g_strfreev (actions);
|
||||
|
||||
g_action_muxer_free_group (group);
|
||||
@@ -504,3 +700,77 @@ g_action_muxer_new (void)
|
||||
{
|
||||
return g_object_new (G_TYPE_ACTION_MUXER, NULL);
|
||||
}
|
||||
|
||||
/* g_action_muxer_get_parent:
|
||||
* @muxer: a #GActionMuxer
|
||||
*
|
||||
* Returns: (transfer-none): the parent of @muxer, or NULL.
|
||||
*/
|
||||
GActionMuxer *
|
||||
g_action_muxer_get_parent (GActionMuxer *muxer)
|
||||
{
|
||||
g_return_val_if_fail (G_IS_ACTION_MUXER (muxer), NULL);
|
||||
|
||||
return muxer->parent;
|
||||
}
|
||||
|
||||
/* g_action_muxer_set_parent:
|
||||
* @muxer: a #GActionMuxer
|
||||
* @parent: (allow-none): the new parent #GActionMuxer
|
||||
*
|
||||
* Sets the parent of @muxer to @parent.
|
||||
*/
|
||||
void
|
||||
g_action_muxer_set_parent (GActionMuxer *muxer,
|
||||
GActionMuxer *parent)
|
||||
{
|
||||
g_return_if_fail (G_IS_ACTION_MUXER (muxer));
|
||||
g_return_if_fail (parent == NULL || G_IS_ACTION_MUXER (parent));
|
||||
|
||||
if (muxer->parent == parent)
|
||||
return;
|
||||
|
||||
if (muxer->parent != NULL)
|
||||
{
|
||||
gchar **actions;
|
||||
gchar **it;
|
||||
|
||||
actions = g_action_group_list_actions (G_ACTION_GROUP (muxer->parent));
|
||||
for (it = actions; *it; it++)
|
||||
g_action_muxer_action_removed (muxer, *it);
|
||||
g_strfreev (actions);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (muxer->parent, g_action_muxer_action_added_to_parent, muxer);
|
||||
g_signal_handlers_disconnect_by_func (muxer->parent, g_action_muxer_action_removed_from_parent, muxer);
|
||||
g_signal_handlers_disconnect_by_func (muxer->parent, g_action_muxer_parent_action_enabled_changed, muxer);
|
||||
g_signal_handlers_disconnect_by_func (muxer->parent, g_action_muxer_parent_action_state_changed, muxer);
|
||||
|
||||
g_object_unref (muxer->parent);
|
||||
}
|
||||
|
||||
muxer->parent = parent;
|
||||
|
||||
if (muxer->parent != NULL)
|
||||
{
|
||||
gchar **actions;
|
||||
gchar **it;
|
||||
|
||||
g_object_ref (muxer->parent);
|
||||
|
||||
actions = g_action_group_list_actions (G_ACTION_GROUP (muxer->parent));
|
||||
for (it = actions; *it; it++)
|
||||
g_action_muxer_action_added (muxer, *it, G_ACTION_GROUP (muxer->parent), *it);
|
||||
g_strfreev (actions);
|
||||
|
||||
g_signal_connect (muxer->parent, "action-added",
|
||||
G_CALLBACK (g_action_muxer_action_added_to_parent), muxer);
|
||||
g_signal_connect (muxer->parent, "action-removed",
|
||||
G_CALLBACK (g_action_muxer_action_removed_from_parent), muxer);
|
||||
g_signal_connect (muxer->parent, "action-enabled-changed",
|
||||
G_CALLBACK (g_action_muxer_parent_action_enabled_changed), muxer);
|
||||
g_signal_connect (muxer->parent, "action-state-changed",
|
||||
G_CALLBACK (g_action_muxer_parent_action_state_changed), muxer);
|
||||
}
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (muxer), properties[PROP_PARENT]);
|
||||
}
|
||||
|
||||
@@ -46,6 +46,13 @@ G_GNUC_INTERNAL
|
||||
void g_action_muxer_remove (GActionMuxer *muxer,
|
||||
const gchar *prefix);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GActionMuxer * g_action_muxer_get_parent (GActionMuxer *muxer);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void g_action_muxer_set_parent (GActionMuxer *muxer,
|
||||
GActionMuxer *parent);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __G_ACTION_MUXER_H__ */
|
||||
|
||||
@@ -1,286 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2012 Canonical Limited
|
||||
*
|
||||
* 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
|
||||
* licence 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Ryan Lortie <desrt@desrt.ca>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gsimpleactionobserver.h"
|
||||
#include "gactionobservable.h"
|
||||
|
||||
typedef GObjectClass GSimpleActionObserverClass;
|
||||
struct _GSimpleActionObserver
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GActionGroup *action_group;
|
||||
gchar *action_name;
|
||||
GVariant *target;
|
||||
|
||||
gboolean can_activate;
|
||||
gboolean active;
|
||||
gboolean enabled;
|
||||
|
||||
gint reporting;
|
||||
};
|
||||
|
||||
static void g_simple_action_observer_init_iface (GActionObserverInterface *iface);
|
||||
G_DEFINE_TYPE_WITH_CODE (GSimpleActionObserver, g_simple_action_observer, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_OBSERVER, g_simple_action_observer_init_iface));
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_ACTIVE,
|
||||
PROP_ENABLED,
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
static GParamSpec *g_simple_action_observer_pspecs[N_PROPS];
|
||||
|
||||
static void
|
||||
g_simple_action_observer_action_added (GActionObserver *g_observer,
|
||||
GActionObservable *observable,
|
||||
const gchar *action_name,
|
||||
const GVariantType *parameter_type,
|
||||
gboolean enabled,
|
||||
GVariant *state)
|
||||
{
|
||||
GSimpleActionObserver *observer = G_SIMPLE_ACTION_OBSERVER (g_observer);
|
||||
gboolean active;
|
||||
|
||||
/* we can only activate if we have the correct type of parameter */
|
||||
observer->can_activate = (observer->target == NULL && parameter_type == NULL) ||
|
||||
(observer->target != NULL && parameter_type != NULL &&
|
||||
g_variant_is_of_type (observer->target, parameter_type));
|
||||
|
||||
if (observer->can_activate)
|
||||
{
|
||||
if (observer->target != NULL && state != NULL)
|
||||
active = g_variant_equal (state, observer->target);
|
||||
|
||||
else if (state != NULL && g_variant_is_of_type (state, G_VARIANT_TYPE_BOOLEAN))
|
||||
active = g_variant_get_boolean (state);
|
||||
|
||||
else
|
||||
active = FALSE;
|
||||
|
||||
if (active != observer->active)
|
||||
{
|
||||
observer->active = active;
|
||||
observer->reporting++;
|
||||
g_object_notify_by_pspec (G_OBJECT (observer), g_simple_action_observer_pspecs[PROP_ACTIVE]);
|
||||
observer->reporting--;
|
||||
}
|
||||
|
||||
if (enabled != observer->enabled)
|
||||
{
|
||||
observer->enabled = enabled;
|
||||
g_object_notify_by_pspec (G_OBJECT (observer), g_simple_action_observer_pspecs[PROP_ENABLED]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
g_simple_action_observer_action_enabled_changed (GActionObserver *g_observer,
|
||||
GActionObservable *observable,
|
||||
const gchar *action_name,
|
||||
gboolean enabled)
|
||||
{
|
||||
GSimpleActionObserver *observer = G_SIMPLE_ACTION_OBSERVER (g_observer);
|
||||
|
||||
if (!observer->can_activate)
|
||||
return;
|
||||
|
||||
if (enabled != observer->enabled)
|
||||
{
|
||||
observer->enabled = enabled;
|
||||
g_object_notify_by_pspec (G_OBJECT (observer), g_simple_action_observer_pspecs[PROP_ENABLED]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
g_simple_action_observer_action_state_changed (GActionObserver *g_observer,
|
||||
GActionObservable *observable,
|
||||
const gchar *action_name,
|
||||
GVariant *state)
|
||||
{
|
||||
GSimpleActionObserver *observer = G_SIMPLE_ACTION_OBSERVER (g_observer);
|
||||
gboolean active = FALSE;
|
||||
|
||||
if (!observer->can_activate)
|
||||
return;
|
||||
|
||||
if (observer->target)
|
||||
active = g_variant_equal (state, observer->target);
|
||||
|
||||
else if (g_variant_is_of_type (state, G_VARIANT_TYPE_BOOLEAN))
|
||||
active = g_variant_get_boolean (state);
|
||||
|
||||
if (active != observer->active)
|
||||
{
|
||||
observer->active = active;
|
||||
observer->reporting++;
|
||||
g_object_notify_by_pspec (G_OBJECT (observer), g_simple_action_observer_pspecs[PROP_ACTIVE]);
|
||||
observer->reporting--;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
g_simple_action_observer_action_removed (GActionObserver *g_observer,
|
||||
GActionObservable *observable,
|
||||
const gchar *action_name)
|
||||
{
|
||||
GSimpleActionObserver *observer = G_SIMPLE_ACTION_OBSERVER (g_observer);
|
||||
|
||||
if (!observer->can_activate)
|
||||
return;
|
||||
|
||||
observer->can_activate = FALSE;
|
||||
|
||||
if (observer->active)
|
||||
{
|
||||
observer->active = FALSE;
|
||||
observer->reporting++;
|
||||
g_object_notify_by_pspec (G_OBJECT (observer), g_simple_action_observer_pspecs[PROP_ACTIVE]);
|
||||
observer->reporting--;
|
||||
}
|
||||
|
||||
if (observer->enabled)
|
||||
{
|
||||
observer->enabled = FALSE;
|
||||
g_object_notify_by_pspec (G_OBJECT (observer), g_simple_action_observer_pspecs[PROP_ENABLED]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
g_simple_action_observer_get_property (GObject *object, guint prop_id,
|
||||
GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
GSimpleActionObserver *observer = G_SIMPLE_ACTION_OBSERVER (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ACTIVE:
|
||||
g_value_set_boolean (value, observer->active);
|
||||
break;
|
||||
|
||||
case PROP_ENABLED:
|
||||
g_value_set_boolean (value, observer->enabled);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
g_simple_action_observer_finalize (GObject *object)
|
||||
{
|
||||
GSimpleActionObserver *observer = G_SIMPLE_ACTION_OBSERVER (object);
|
||||
|
||||
g_object_unref (observer->action_group);
|
||||
g_free (observer->action_name);
|
||||
|
||||
if (observer->target)
|
||||
g_variant_unref (observer->target);
|
||||
|
||||
G_OBJECT_CLASS (g_simple_action_observer_parent_class)
|
||||
->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
g_simple_action_observer_init (GSimpleActionObserver *observer)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
g_simple_action_observer_init_iface (GActionObserverInterface *iface)
|
||||
{
|
||||
iface->action_added = g_simple_action_observer_action_added;
|
||||
iface->action_enabled_changed = g_simple_action_observer_action_enabled_changed;
|
||||
iface->action_state_changed = g_simple_action_observer_action_state_changed;
|
||||
iface->action_removed = g_simple_action_observer_action_removed;
|
||||
}
|
||||
|
||||
static void
|
||||
g_simple_action_observer_class_init (GObjectClass *class)
|
||||
{
|
||||
class->get_property = g_simple_action_observer_get_property;
|
||||
class->finalize = g_simple_action_observer_finalize;
|
||||
|
||||
g_simple_action_observer_pspecs[PROP_ACTIVE] = g_param_spec_boolean ("active", "active", "active", FALSE,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
g_simple_action_observer_pspecs[PROP_ENABLED] = g_param_spec_boolean ("enabled", "enabled", "enabled", FALSE,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_properties (class, N_PROPS, g_simple_action_observer_pspecs);
|
||||
}
|
||||
|
||||
GSimpleActionObserver *
|
||||
g_simple_action_observer_new (GActionObservable *observable,
|
||||
const gchar *action_name,
|
||||
GVariant *target)
|
||||
{
|
||||
GSimpleActionObserver *observer;
|
||||
const GVariantType *type;
|
||||
gboolean enabled;
|
||||
GVariant *state;
|
||||
|
||||
observer = g_object_new (G_TYPE_SIMPLE_ACTION_OBSERVER, NULL);
|
||||
observer->action_group = g_object_ref (observable);
|
||||
observer->action_name = g_strdup (action_name);
|
||||
if (target)
|
||||
observer->target = g_variant_ref_sink (target);
|
||||
|
||||
g_action_observable_register_observer (observable, action_name, G_ACTION_OBSERVER (observer));
|
||||
|
||||
if (g_action_group_query_action (observer->action_group, action_name, &enabled, &type, NULL, NULL, &state))
|
||||
{
|
||||
g_simple_action_observer_action_added (G_ACTION_OBSERVER (observer), observable,
|
||||
action_name, type, enabled, state);
|
||||
if (state)
|
||||
g_variant_unref (state);
|
||||
}
|
||||
|
||||
return observer;
|
||||
}
|
||||
|
||||
void
|
||||
g_simple_action_observer_activate (GSimpleActionObserver *observer)
|
||||
{
|
||||
g_return_if_fail (G_IS_SIMPLE_ACTION_OBSERVER (observer));
|
||||
|
||||
if (observer->can_activate && !observer->reporting)
|
||||
g_action_group_activate_action (G_ACTION_GROUP (observer->action_group),
|
||||
observer->action_name, observer->target);
|
||||
}
|
||||
|
||||
gboolean
|
||||
g_simple_action_observer_get_active (GSimpleActionObserver *observer)
|
||||
{
|
||||
g_return_val_if_fail (G_IS_SIMPLE_ACTION_OBSERVER (observer), FALSE);
|
||||
|
||||
return observer->active;
|
||||
}
|
||||
|
||||
gboolean
|
||||
g_simple_action_observer_get_enabled (GSimpleActionObserver *observer)
|
||||
{
|
||||
g_return_val_if_fail (G_IS_SIMPLE_ACTION_OBSERVER (observer), FALSE);
|
||||
|
||||
return observer->enabled;
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2012 Canonical Limited
|
||||
*
|
||||
* 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
|
||||
* licence 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Ryan Lortie <desrt@desrt.ca>
|
||||
*/
|
||||
|
||||
#ifndef __G_SIMPLE_ACTION_OBSERVER_H__
|
||||
#define __G_SIMPLE_ACTION_OBSERVER_H__
|
||||
|
||||
#include "gactionobserver.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define G_TYPE_SIMPLE_ACTION_OBSERVER (g_simple_action_observer_get_type ())
|
||||
#define G_SIMPLE_ACTION_OBSERVER(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
|
||||
G_TYPE_SIMPLE_ACTION_OBSERVER, \
|
||||
GSimpleActionObserver))
|
||||
#define G_IS_SIMPLE_ACTION_OBSERVER(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \
|
||||
G_TYPE_SIMPLE_ACTION_OBSERVER))
|
||||
|
||||
typedef struct _GSimpleActionObserver GSimpleActionObserver;
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GType g_simple_action_observer_get_type (void);
|
||||
G_GNUC_INTERNAL
|
||||
GSimpleActionObserver * g_simple_action_observer_new (GActionObservable *observable,
|
||||
const gchar *action_name,
|
||||
GVariant *target);
|
||||
G_GNUC_INTERNAL
|
||||
void g_simple_action_observer_activate (GSimpleActionObserver *observer);
|
||||
G_GNUC_INTERNAL
|
||||
gboolean g_simple_action_observer_get_active (GSimpleActionObserver *observer);
|
||||
G_GNUC_INTERNAL
|
||||
gboolean g_simple_action_observer_get_enabled (GSimpleActionObserver *observer);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __G_SIMPLE_ACTION_OBSERVER_H__ */
|
||||
@@ -246,6 +246,7 @@ gtk_application_window_get_type
|
||||
gtk_application_window_get_id
|
||||
gtk_application_window_new
|
||||
gtk_application_window_set_show_menubar
|
||||
gtk_application_get_active_window
|
||||
gtk_arrow_get_type
|
||||
gtk_arrow_new
|
||||
gtk_arrow_placement_get_type
|
||||
@@ -907,6 +908,8 @@ gtk_entry_get_icon_storage_type
|
||||
gtk_entry_get_icon_tooltip_markup
|
||||
gtk_entry_get_icon_tooltip_text
|
||||
gtk_entry_get_inner_border
|
||||
gtk_entry_get_input_hints
|
||||
gtk_entry_get_input_purpose
|
||||
gtk_entry_get_invisible_char
|
||||
gtk_entry_get_layout
|
||||
gtk_entry_get_layout_offsets
|
||||
@@ -944,6 +947,8 @@ gtk_entry_set_icon_sensitive
|
||||
gtk_entry_set_icon_tooltip_markup
|
||||
gtk_entry_set_icon_tooltip_text
|
||||
gtk_entry_set_inner_border
|
||||
gtk_entry_set_input_hints
|
||||
gtk_entry_set_input_purpose
|
||||
gtk_entry_set_invisible_char
|
||||
gtk_entry_set_max_length
|
||||
gtk_entry_set_overwrite_mode
|
||||
@@ -1436,6 +1441,8 @@ gtk_init_abi_check
|
||||
gtk_init_check_abi_check
|
||||
#endif
|
||||
gtk_init_with_args
|
||||
gtk_input_hints_get_type
|
||||
gtk_input_purpose_get_type
|
||||
gtk_invisible_get_screen
|
||||
gtk_invisible_get_type
|
||||
gtk_invisible_new
|
||||
@@ -1550,16 +1557,18 @@ gtk_menu_bar_new
|
||||
gtk_menu_bar_new_from_model
|
||||
gtk_menu_bar_set_child_pack_direction
|
||||
gtk_menu_bar_set_pack_direction
|
||||
gtk_menu_button_get_type
|
||||
gtk_menu_button_new
|
||||
gtk_menu_button_get_align_widget
|
||||
gtk_menu_button_get_direction
|
||||
gtk_menu_button_get_menu
|
||||
gtk_menu_button_get_menu_model
|
||||
gtk_menu_button_get_popup
|
||||
gtk_menu_button_get_type
|
||||
gtk_menu_button_new
|
||||
gtk_menu_button_set_align_widget
|
||||
gtk_menu_button_set_direction
|
||||
gtk_menu_button_set_menu
|
||||
gtk_menu_button_set_menu_model
|
||||
gtk_menu_button_set_popup
|
||||
gtk_menu_detach
|
||||
gtk_menu_direction_type_get_type
|
||||
gtk_menu_get_accel_group
|
||||
@@ -3003,6 +3012,8 @@ gtk_text_view_get_default_attributes
|
||||
gtk_text_view_get_editable
|
||||
gtk_text_view_get_hadjustment
|
||||
gtk_text_view_get_indent
|
||||
gtk_text_view_get_input_hints
|
||||
gtk_text_view_get_input_purpose
|
||||
gtk_text_view_get_iter_at_location
|
||||
gtk_text_view_get_iter_at_position
|
||||
gtk_text_view_get_iter_location
|
||||
@@ -3039,6 +3050,8 @@ gtk_text_view_set_buffer
|
||||
gtk_text_view_set_cursor_visible
|
||||
gtk_text_view_set_editable
|
||||
gtk_text_view_set_indent
|
||||
gtk_text_view_set_input_hints
|
||||
gtk_text_view_set_input_purpose
|
||||
gtk_text_view_set_justification
|
||||
gtk_text_view_set_left_margin
|
||||
gtk_text_view_set_overwrite
|
||||
@@ -3827,6 +3840,7 @@ gtk_widget_unmap
|
||||
gtk_widget_unparent
|
||||
gtk_widget_unrealize
|
||||
gtk_widget_unset_state_flags
|
||||
gtk_widget_insert_action_group
|
||||
#ifdef GDK_WINDOWING_WIN32
|
||||
gtk_win32_embed_widget_get_type
|
||||
#endif
|
||||
|
||||
@@ -791,18 +791,20 @@ _gtk_action_emit_activate (GtkAction *action)
|
||||
{
|
||||
GtkActionGroup *group = action->private_data->action_group;
|
||||
|
||||
if (group != NULL)
|
||||
if (group != NULL)
|
||||
{
|
||||
g_object_ref (action);
|
||||
g_object_ref (group);
|
||||
_gtk_action_group_emit_pre_activate (group, action);
|
||||
}
|
||||
|
||||
g_signal_emit (action, action_signals[ACTIVATE], 0);
|
||||
g_signal_emit (action, action_signals[ACTIVATE], 0);
|
||||
|
||||
if (group != NULL)
|
||||
if (group != NULL)
|
||||
{
|
||||
_gtk_action_group_emit_post_activate (group, action);
|
||||
g_object_unref (group);
|
||||
g_object_unref (action);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,638 @@
|
||||
/*
|
||||
* Copyright © 2012 Canonical Limited
|
||||
*
|
||||
* 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
|
||||
* licence 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Ryan Lortie <desrt@desrt.ca>
|
||||
*/
|
||||
|
||||
#include "gtkactionhelper.h"
|
||||
#include "gactionobservable.h"
|
||||
|
||||
#include "gtkwidget.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GActionGroup *group;
|
||||
|
||||
GHashTable *watchers;
|
||||
} GtkActionHelperGroup;
|
||||
|
||||
static void gtk_action_helper_action_added (GtkActionHelper *helper,
|
||||
gboolean enabled,
|
||||
const GVariantType *parameter_type,
|
||||
GVariant *state,
|
||||
gboolean should_emit_signals);
|
||||
|
||||
static void gtk_action_helper_action_removed (GtkActionHelper *helper);
|
||||
|
||||
static void gtk_action_helper_action_enabled_changed (GtkActionHelper *helper,
|
||||
gboolean enabled);
|
||||
|
||||
static void gtk_action_helper_action_state_changed (GtkActionHelper *helper,
|
||||
GVariant *new_state);
|
||||
|
||||
typedef GObjectClass GtkActionHelperClass;
|
||||
|
||||
struct _GtkActionHelper
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GtkApplication *application;
|
||||
GtkWidget *widget;
|
||||
|
||||
GtkActionHelperGroup *group;
|
||||
|
||||
GActionMuxer *action_context;
|
||||
gchar *action_name;
|
||||
|
||||
GVariant *target;
|
||||
|
||||
GtkActionHelperRole role;
|
||||
gboolean can_activate;
|
||||
gboolean enabled;
|
||||
gboolean active;
|
||||
|
||||
gint reporting;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_ENABLED,
|
||||
PROP_ACTIVE,
|
||||
PROP_ROLE,
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
static GParamSpec *gtk_action_helper_pspecs[N_PROPS];
|
||||
|
||||
static void gtk_action_helper_observer_iface_init (GActionObserverInterface *iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkActionHelper, gtk_action_helper, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_OBSERVER, gtk_action_helper_observer_iface_init))
|
||||
|
||||
static void
|
||||
gtk_action_helper_report_change (GtkActionHelper *helper,
|
||||
guint prop_id)
|
||||
{
|
||||
helper->reporting++;
|
||||
|
||||
if (!helper->application)
|
||||
{
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ENABLED:
|
||||
gtk_widget_set_sensitive (GTK_WIDGET (helper->widget), helper->enabled);
|
||||
break;
|
||||
|
||||
case PROP_ACTIVE:
|
||||
{
|
||||
GParamSpec *pspec;
|
||||
|
||||
pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (helper->widget), "active");
|
||||
|
||||
if (pspec && G_PARAM_SPEC_VALUE_TYPE (pspec) == G_TYPE_BOOLEAN)
|
||||
g_object_set (G_OBJECT (helper->widget), "active", helper->active, NULL);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_ROLE:
|
||||
{
|
||||
GParamSpec *pspec;
|
||||
|
||||
pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (helper->widget), "action-role");
|
||||
|
||||
if (pspec && G_PARAM_SPEC_VALUE_TYPE (pspec) == G_TYPE_UINT)
|
||||
g_object_set (G_OBJECT (helper->widget), "action-role", helper->role, NULL);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (helper), gtk_action_helper_pspecs[prop_id]);
|
||||
helper->reporting--;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_action_helper_action_added (GtkActionHelper *helper,
|
||||
gboolean enabled,
|
||||
const GVariantType *parameter_type,
|
||||
GVariant *state,
|
||||
gboolean should_emit_signals)
|
||||
{
|
||||
/* we can only activate if we have the correct type of parameter */
|
||||
helper->can_activate = (helper->target == NULL && parameter_type == NULL) ||
|
||||
(helper->target != NULL && parameter_type != NULL &&
|
||||
g_variant_is_of_type (helper->target, parameter_type));
|
||||
|
||||
if (!helper->can_activate)
|
||||
return;
|
||||
|
||||
helper->enabled = enabled;
|
||||
|
||||
if (helper->target != NULL && state != NULL)
|
||||
{
|
||||
helper->active = g_variant_equal (state, helper->target);
|
||||
helper->role = GTK_ACTION_HELPER_ROLE_RADIO;
|
||||
}
|
||||
|
||||
else if (state != NULL && g_variant_is_of_type (state, G_VARIANT_TYPE_BOOLEAN))
|
||||
{
|
||||
helper->active = g_variant_get_boolean (state);
|
||||
helper->role = GTK_ACTION_HELPER_ROLE_TOGGLE;
|
||||
}
|
||||
|
||||
if (should_emit_signals)
|
||||
{
|
||||
if (helper->enabled)
|
||||
gtk_action_helper_report_change (helper, PROP_ENABLED);
|
||||
|
||||
if (helper->active)
|
||||
gtk_action_helper_report_change (helper, PROP_ACTIVE);
|
||||
|
||||
if (helper->role)
|
||||
gtk_action_helper_report_change (helper, PROP_ROLE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_action_helper_action_removed (GtkActionHelper *helper)
|
||||
{
|
||||
if (!helper->can_activate)
|
||||
return;
|
||||
|
||||
helper->can_activate = FALSE;
|
||||
|
||||
if (helper->enabled)
|
||||
{
|
||||
helper->enabled = FALSE;
|
||||
gtk_action_helper_report_change (helper, PROP_ENABLED);
|
||||
}
|
||||
|
||||
if (helper->active)
|
||||
{
|
||||
helper->enabled = FALSE;
|
||||
gtk_action_helper_report_change (helper, PROP_ACTIVE);
|
||||
}
|
||||
|
||||
if (helper->role)
|
||||
{
|
||||
helper->role = GTK_ACTION_HELPER_ROLE_NORMAL;
|
||||
gtk_action_helper_report_change (helper, PROP_ROLE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_action_helper_action_enabled_changed (GtkActionHelper *helper,
|
||||
gboolean enabled)
|
||||
{
|
||||
if (!helper->can_activate)
|
||||
return;
|
||||
|
||||
if (helper->enabled == enabled)
|
||||
return;
|
||||
|
||||
helper->enabled = enabled;
|
||||
gtk_action_helper_report_change (helper, PROP_ENABLED);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_action_helper_action_state_changed (GtkActionHelper *helper,
|
||||
GVariant *new_state)
|
||||
{
|
||||
gboolean was_active;
|
||||
|
||||
if (!helper->can_activate)
|
||||
return;
|
||||
|
||||
was_active = helper->active;
|
||||
|
||||
if (helper->target)
|
||||
helper->active = g_variant_equal (new_state, helper->target);
|
||||
|
||||
else if (g_variant_is_of_type (new_state, G_VARIANT_TYPE_BOOLEAN))
|
||||
helper->active = g_variant_get_boolean (new_state);
|
||||
|
||||
else
|
||||
helper->active = FALSE;
|
||||
|
||||
if (helper->active != was_active)
|
||||
gtk_action_helper_report_change (helper, PROP_ACTIVE);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_action_helper_get_property (GObject *object, guint prop_id,
|
||||
GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
GtkActionHelper *helper = GTK_ACTION_HELPER (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ENABLED:
|
||||
g_value_set_boolean (value, helper->enabled);
|
||||
break;
|
||||
|
||||
case PROP_ACTIVE:
|
||||
g_value_set_boolean (value, helper->active);
|
||||
break;
|
||||
|
||||
case PROP_ROLE:
|
||||
g_value_set_uint (value, helper->role);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_action_helper_finalize (GObject *object)
|
||||
{
|
||||
GtkActionHelper *helper = GTK_ACTION_HELPER (object);
|
||||
|
||||
if (helper->application)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_data (helper->application, helper);
|
||||
g_object_unref (helper->action_context);
|
||||
g_object_unref (helper->application);
|
||||
|
||||
if (helper->widget)
|
||||
g_object_unref (helper->widget);
|
||||
}
|
||||
|
||||
g_free (helper->action_name);
|
||||
|
||||
if (helper->target)
|
||||
g_variant_unref (helper->target);
|
||||
|
||||
G_OBJECT_CLASS (gtk_action_helper_parent_class)
|
||||
->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_action_helper_observer_action_added (GActionObserver *observer,
|
||||
GActionObservable *observable,
|
||||
const gchar *action_name,
|
||||
const GVariantType *parameter_type,
|
||||
gboolean enabled,
|
||||
GVariant *state)
|
||||
{
|
||||
gtk_action_helper_action_added (GTK_ACTION_HELPER (observer), enabled, parameter_type, state, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_action_helper_observer_action_enabled_changed (GActionObserver *observer,
|
||||
GActionObservable *observable,
|
||||
const gchar *action_name,
|
||||
gboolean enabled)
|
||||
{
|
||||
gtk_action_helper_action_enabled_changed (GTK_ACTION_HELPER (observer), enabled);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_action_helper_observer_action_state_changed (GActionObserver *observer,
|
||||
GActionObservable *observable,
|
||||
const gchar *action_name,
|
||||
GVariant *state)
|
||||
{
|
||||
gtk_action_helper_action_state_changed (GTK_ACTION_HELPER (observer), state);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_action_helper_observer_action_removed (GActionObserver *observer,
|
||||
GActionObservable *observable,
|
||||
const gchar *action_name)
|
||||
{
|
||||
gtk_action_helper_action_removed (GTK_ACTION_HELPER (observer));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_action_helper_init (GtkActionHelper *helper)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_action_helper_class_init (GtkActionHelperClass *class)
|
||||
{
|
||||
class->get_property = gtk_action_helper_get_property;
|
||||
class->finalize = gtk_action_helper_finalize;
|
||||
|
||||
gtk_action_helper_pspecs[PROP_ENABLED] = g_param_spec_boolean ("enabled", "enabled", "enabled", FALSE,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
gtk_action_helper_pspecs[PROP_ACTIVE] = g_param_spec_boolean ("active", "active", "active", FALSE,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
gtk_action_helper_pspecs[PROP_ROLE] = g_param_spec_uint ("role", "role", "role", 0, 2, 0,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_properties (class, N_PROPS, gtk_action_helper_pspecs);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_action_helper_observer_iface_init (GActionObserverInterface *iface)
|
||||
{
|
||||
iface->action_added = gtk_action_helper_observer_action_added;
|
||||
iface->action_enabled_changed = gtk_action_helper_observer_action_enabled_changed;
|
||||
iface->action_state_changed = gtk_action_helper_observer_action_state_changed;
|
||||
iface->action_removed = gtk_action_helper_observer_action_removed;
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gtk_action_helper_new:
|
||||
* @widget: a #GtkWidget implementing #GtkActionable
|
||||
*
|
||||
* Creates a helper to track the state of a named action. This will
|
||||
* usually be used by widgets implementing #GtkActionable.
|
||||
*
|
||||
* This helper class is usually used by @widget itself. In order to
|
||||
* avoid reference cycles, the helper does not hold a reference on
|
||||
* @widget, but will assume that it continues to exist for the duration
|
||||
* of the life of the helper. If you are using the helper from outside
|
||||
* of the widget, you should take a ref on @widget for each ref you hold
|
||||
* on the helper.
|
||||
*
|
||||
* Returns: a new #GtkActionHelper
|
||||
*/
|
||||
GtkActionHelper *
|
||||
gtk_action_helper_new (GtkActionable *widget)
|
||||
{
|
||||
GtkActionHelper *helper;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_ACTIONABLE (widget), NULL);
|
||||
helper = g_object_new (GTK_TYPE_ACTION_HELPER, NULL);
|
||||
|
||||
helper->widget = GTK_WIDGET (widget);
|
||||
|
||||
if (helper->widget)
|
||||
{
|
||||
GParamSpec *pspec;
|
||||
|
||||
helper->enabled = gtk_widget_get_sensitive (GTK_WIDGET (helper->widget));
|
||||
|
||||
pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (helper->widget), "active");
|
||||
if (pspec && G_PARAM_SPEC_VALUE_TYPE (pspec) == G_TYPE_BOOLEAN)
|
||||
g_object_get (G_OBJECT (helper->widget), "active", &helper->active, NULL);
|
||||
}
|
||||
|
||||
helper->action_context = _gtk_widget_get_action_muxer (GTK_WIDGET (widget));
|
||||
|
||||
return helper;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_action_helper_active_window_changed (GObject *object,
|
||||
GParamSpec *pspec,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkActionHelper *helper = user_data;
|
||||
GActionMuxer *parent;
|
||||
|
||||
if (helper->widget)
|
||||
g_object_unref (helper->widget);
|
||||
|
||||
helper->widget = GTK_WIDGET (gtk_application_get_active_window (helper->application));
|
||||
|
||||
if (helper->widget)
|
||||
{
|
||||
parent = g_object_ref (_gtk_widget_get_action_muxer (GTK_WIDGET (helper->widget)));
|
||||
g_object_ref (helper->widget);
|
||||
}
|
||||
else
|
||||
{
|
||||
parent = g_action_muxer_new ();
|
||||
g_action_muxer_insert (parent, "app", G_ACTION_GROUP (helper->application));
|
||||
}
|
||||
|
||||
g_action_muxer_set_parent (helper->action_context, parent);
|
||||
g_object_unref (parent);
|
||||
}
|
||||
|
||||
GtkActionHelper *
|
||||
gtk_action_helper_new_with_application (GtkApplication *application)
|
||||
{
|
||||
GtkActionHelper *helper;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_APPLICATION (application), NULL);
|
||||
|
||||
helper = g_object_new (GTK_TYPE_ACTION_HELPER, NULL);
|
||||
helper->application = g_object_ref (application);
|
||||
|
||||
helper->action_context = g_action_muxer_new ();
|
||||
g_signal_connect (application, "notify::active-window", G_CALLBACK (gtk_action_helper_active_window_changed), helper);
|
||||
gtk_action_helper_active_window_changed (NULL, NULL, helper);
|
||||
|
||||
return helper;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_action_helper_set_action_name (GtkActionHelper *helper,
|
||||
const gchar *action_name)
|
||||
{
|
||||
gboolean was_enabled, was_active;
|
||||
GtkActionHelperRole old_role;
|
||||
const GVariantType *parameter_type;
|
||||
gboolean enabled;
|
||||
GVariant *state;
|
||||
|
||||
if (g_strcmp0 (action_name, helper->action_name) == 0)
|
||||
return;
|
||||
|
||||
if (helper->action_name)
|
||||
{
|
||||
g_action_observable_unregister_observer (G_ACTION_OBSERVABLE (helper->action_context),
|
||||
helper->action_name,
|
||||
G_ACTION_OBSERVER (helper));
|
||||
g_free (helper->action_name);
|
||||
}
|
||||
|
||||
helper->action_name = g_strdup (action_name);
|
||||
|
||||
g_action_observable_register_observer (G_ACTION_OBSERVABLE (helper->action_context),
|
||||
helper->action_name,
|
||||
G_ACTION_OBSERVER (helper));
|
||||
|
||||
/* Start by recording the current state of our properties so we know
|
||||
* what notify signals we will need to send.
|
||||
*/
|
||||
was_enabled = helper->enabled;
|
||||
was_active = helper->active;
|
||||
old_role = helper->role;
|
||||
|
||||
if (g_action_group_query_action (G_ACTION_GROUP (helper->action_context), helper->action_name,
|
||||
&enabled, ¶meter_type, NULL, NULL, &state))
|
||||
{
|
||||
gtk_action_helper_action_added (helper, enabled, parameter_type, state, FALSE);
|
||||
|
||||
if (state)
|
||||
g_variant_unref (state);
|
||||
}
|
||||
else
|
||||
{
|
||||
helper->enabled = FALSE;
|
||||
}
|
||||
|
||||
/* Send the notifies for the properties that changed.
|
||||
*
|
||||
* When called during construction, widget is NULL. We don't need to
|
||||
* report in that case.
|
||||
*/
|
||||
if (helper->enabled != was_enabled)
|
||||
gtk_action_helper_report_change (helper, PROP_ENABLED);
|
||||
|
||||
if (helper->active != was_active)
|
||||
gtk_action_helper_report_change (helper, PROP_ACTIVE);
|
||||
|
||||
if (helper->role != old_role)
|
||||
gtk_action_helper_report_change (helper, PROP_ROLE);
|
||||
|
||||
if (!helper->application)
|
||||
g_object_notify (G_OBJECT (helper->widget), "action-name");
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gtk_action_helper_set_action_target_value:
|
||||
* @helper: a #GtkActionHelper
|
||||
* @target_value: an action target, as per #GtkActionable
|
||||
*
|
||||
* This function consumes @action_target if it is floating.
|
||||
*/
|
||||
void
|
||||
gtk_action_helper_set_action_target_value (GtkActionHelper *helper,
|
||||
GVariant *target_value)
|
||||
{
|
||||
gboolean was_enabled;
|
||||
gboolean was_active;
|
||||
|
||||
if (target_value == helper->target)
|
||||
return;
|
||||
|
||||
if (target_value && helper->target && g_variant_equal (target_value, helper->target))
|
||||
{
|
||||
g_variant_unref (g_variant_ref_sink (target_value));
|
||||
return;
|
||||
}
|
||||
|
||||
if (helper->target)
|
||||
{
|
||||
g_variant_unref (helper->target);
|
||||
helper->target = NULL;
|
||||
}
|
||||
|
||||
if (target_value)
|
||||
helper->target = g_variant_ref_sink (target_value);
|
||||
|
||||
/* The action_name has not yet been set. Don't do anything yet. */
|
||||
if (helper->action_name == NULL)
|
||||
return;
|
||||
|
||||
was_enabled = helper->enabled;
|
||||
was_active = helper->active;
|
||||
|
||||
/* If we are attached to an action group then it is possible that this
|
||||
* change of the target value could impact our properties (including
|
||||
* changes to 'can_activate' and therefore 'enabled', due to resolving
|
||||
* a parameter type mismatch).
|
||||
*
|
||||
* Start over again by pretending the action gets re-added.
|
||||
*/
|
||||
helper->can_activate = FALSE;
|
||||
helper->enabled = FALSE;
|
||||
helper->active = FALSE;
|
||||
|
||||
if (helper->action_context)
|
||||
{
|
||||
const GVariantType *parameter_type;
|
||||
gboolean enabled;
|
||||
GVariant *state;
|
||||
|
||||
if (g_action_group_query_action (G_ACTION_GROUP (helper->action_context),
|
||||
helper->action_name, &enabled, ¶meter_type,
|
||||
NULL, NULL, &state))
|
||||
{
|
||||
gtk_action_helper_action_added (helper, enabled, parameter_type, state, FALSE);
|
||||
|
||||
if (state)
|
||||
g_variant_unref (state);
|
||||
}
|
||||
}
|
||||
|
||||
if (helper->enabled != was_enabled)
|
||||
gtk_action_helper_report_change (helper, PROP_ENABLED);
|
||||
|
||||
if (helper->active != was_active)
|
||||
gtk_action_helper_report_change (helper, PROP_ACTIVE);
|
||||
|
||||
if (!helper->application)
|
||||
g_object_notify (G_OBJECT (helper->widget), "action-target");
|
||||
}
|
||||
|
||||
const gchar *
|
||||
gtk_action_helper_get_action_name (GtkActionHelper *helper)
|
||||
{
|
||||
if (helper == NULL)
|
||||
return NULL;
|
||||
|
||||
return helper->action_name;
|
||||
}
|
||||
|
||||
GVariant *
|
||||
gtk_action_helper_get_action_target_value (GtkActionHelper *helper)
|
||||
{
|
||||
if (helper == NULL)
|
||||
return NULL;
|
||||
|
||||
return helper->target;
|
||||
}
|
||||
|
||||
GtkActionHelperRole
|
||||
gtk_action_helper_get_role (GtkActionHelper *helper)
|
||||
{
|
||||
if (helper == NULL)
|
||||
return GTK_ACTION_HELPER_ROLE_NORMAL;
|
||||
|
||||
return helper->role;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_action_helper_get_enabled (GtkActionHelper *helper)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_ACTION_HELPER (helper), FALSE);
|
||||
|
||||
return helper->enabled;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_action_helper_get_active (GtkActionHelper *helper)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_ACTION_HELPER (helper), FALSE);
|
||||
|
||||
return helper->active;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_action_helper_activate (GtkActionHelper *helper)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_ACTION_HELPER (helper));
|
||||
|
||||
if (!helper->can_activate || helper->reporting)
|
||||
return;
|
||||
|
||||
g_action_group_activate_action (G_ACTION_GROUP (helper->action_context),
|
||||
helper->action_name, helper->target);
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright © 2012 Canonical Limited
|
||||
*
|
||||
* 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
|
||||
* licence 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Ryan Lortie <desrt@desrt.ca>
|
||||
*/
|
||||
|
||||
#ifndef __GTK_ACTION_HELPER_H__
|
||||
#define __GTK_ACTION_HELPER_H__
|
||||
|
||||
#include <gtk/gtkapplication.h>
|
||||
#include <gtk/gtkactionable.h>
|
||||
|
||||
#define GTK_TYPE_ACTION_HELPER (gtk_action_helper_get_type ())
|
||||
#define GTK_ACTION_HELPER(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
|
||||
GTK_TYPE_ACTION_HELPER, GtkActionHelper))
|
||||
#define GTK_IS_ACTION_HELPER(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \
|
||||
GTK_TYPE_ACTION_HELPER))
|
||||
|
||||
typedef struct _GtkActionHelper GtkActionHelper;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GTK_ACTION_HELPER_ROLE_NORMAL,
|
||||
GTK_ACTION_HELPER_ROLE_TOGGLE,
|
||||
GTK_ACTION_HELPER_ROLE_RADIO
|
||||
} GtkActionHelperRole;
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GType gtk_action_helper_get_type (void);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GtkActionHelper * gtk_action_helper_new (GtkActionable *widget);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GtkActionHelper * gtk_action_helper_new_with_application (GtkApplication *application);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void gtk_action_helper_set_action_name (GtkActionHelper *helper,
|
||||
const gchar *action_name);
|
||||
G_GNUC_INTERNAL
|
||||
void gtk_action_helper_set_action_target_value (GtkActionHelper *helper,
|
||||
GVariant *action_target);
|
||||
G_GNUC_INTERNAL
|
||||
const gchar * gtk_action_helper_get_action_name (GtkActionHelper *helper);
|
||||
G_GNUC_INTERNAL
|
||||
GVariant * gtk_action_helper_get_action_target_value (GtkActionHelper *helper);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GtkActionHelperRole gtk_action_helper_get_role (GtkActionHelper *helper);
|
||||
G_GNUC_INTERNAL
|
||||
gboolean gtk_action_helper_get_enabled (GtkActionHelper *helper);
|
||||
G_GNUC_INTERNAL
|
||||
gboolean gtk_action_helper_get_active (GtkActionHelper *helper);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void gtk_action_helper_activate (GtkActionHelper *helper);
|
||||
|
||||
#endif /* __GTK_ACTION_HELPER_H__ */
|
||||
@@ -220,8 +220,8 @@ gtk_adjustment_class_init (GtkAdjustmentClass *class)
|
||||
* GtkAdjustment::changed:
|
||||
* @adjustment: the object which received the signal.
|
||||
*
|
||||
* Emitted when one or more of the #GtkAdjustment fields have been changed,
|
||||
* other than the value field.
|
||||
* Emitted when one or more of the #GtkAdjustment properties have been
|
||||
* changed, other than the #GtkAdjustment:value property.
|
||||
*/
|
||||
adjustment_signals[CHANGED] =
|
||||
g_signal_new (I_("changed"),
|
||||
@@ -236,7 +236,7 @@ gtk_adjustment_class_init (GtkAdjustmentClass *class)
|
||||
* GtkAdjustment::value-changed:
|
||||
* @adjustment: the object which received the signal.
|
||||
*
|
||||
* Emitted when the #GtkAdjustment value field has been changed.
|
||||
* Emitted when the #GtkAdjustment:value property has been changed.
|
||||
*/
|
||||
adjustment_signals[VALUE_CHANGED] =
|
||||
g_signal_new (I_("value-changed"),
|
||||
@@ -470,16 +470,16 @@ gtk_adjustment_get_lower (GtkAdjustment *adjustment)
|
||||
* Sets the minimum value of the adjustment.
|
||||
*
|
||||
* When setting multiple adjustment properties via their individual
|
||||
* setters, multiple "changed" signals will be emitted. However, since
|
||||
* the emission of the "changed" signal is tied to the emission of the
|
||||
* "GObject::notify" signals of the changed properties, it's possible
|
||||
* to compress the "changed" signals into one by calling
|
||||
* setters, multiple #GtkAdjustment::changed signals will be emitted. However, since
|
||||
* the emission of the #GtkAdjustment::changed signal is tied to the emission of the
|
||||
* #GObject::notify signals of the changed properties, it's possible
|
||||
* to compress the #GtkAdjustment::changed signals into one by calling
|
||||
* g_object_freeze_notify() and g_object_thaw_notify() around the
|
||||
* calls to the individual setters.
|
||||
*
|
||||
* Alternatively, using a single g_object_set() for all the properties
|
||||
* to change, or using gtk_adjustment_configure() has the same effect
|
||||
* of compressing "changed" emissions.
|
||||
* of compressing #GtkAdjustment::changed emissions.
|
||||
*
|
||||
* Since: 2.14
|
||||
**/
|
||||
@@ -523,7 +523,7 @@ gtk_adjustment_get_upper (GtkAdjustment *adjustment)
|
||||
* property is nonzero.
|
||||
*
|
||||
* See gtk_adjustment_set_lower() about how to compress multiple
|
||||
* emissions of the "changed" signal when setting multiple adjustment
|
||||
* emissions of the #GtkAdjustment::changed signal when setting multiple adjustment
|
||||
* properties.
|
||||
*
|
||||
* Since: 2.14
|
||||
@@ -564,7 +564,7 @@ gtk_adjustment_get_step_increment (GtkAdjustment *adjustment)
|
||||
* Sets the step increment of the adjustment.
|
||||
*
|
||||
* See gtk_adjustment_set_lower() about how to compress multiple
|
||||
* emissions of the "changed" signal when setting multiple adjustment
|
||||
* emissions of the #GtkAdjustment::changed signal when setting multiple adjustment
|
||||
* properties.
|
||||
*
|
||||
* Since: 2.14
|
||||
@@ -605,7 +605,7 @@ gtk_adjustment_get_page_increment (GtkAdjustment *adjustment)
|
||||
* Sets the page increment of the adjustment.
|
||||
*
|
||||
* See gtk_adjustment_set_lower() about how to compress multiple
|
||||
* emissions of the "changed" signal when setting multiple adjustment
|
||||
* emissions of the #GtkAdjustment::changed signal when setting multiple adjustment
|
||||
* properties.
|
||||
*
|
||||
* Since: 2.14
|
||||
@@ -646,7 +646,7 @@ gtk_adjustment_get_page_size (GtkAdjustment *adjustment)
|
||||
* Sets the page size of the adjustment.
|
||||
*
|
||||
* See gtk_adjustment_set_lower() about how to compress multiple
|
||||
* emissions of the "changed" signal when setting multiple adjustment
|
||||
* emissions of the GtkAdjustment::changed signal when setting multiple adjustment
|
||||
* properties.
|
||||
*
|
||||
* Since: 2.14
|
||||
@@ -673,9 +673,9 @@ gtk_adjustment_set_page_size (GtkAdjustment *adjustment,
|
||||
*
|
||||
* Sets all properties of the adjustment at once.
|
||||
*
|
||||
* Use this function to avoid multiple emissions of the "changed"
|
||||
* Use this function to avoid multiple emissions of the #GtkAdjustment::changed
|
||||
* signal. See gtk_adjustment_set_lower() for an alternative way
|
||||
* of compressing multiple emissions of "changed" into one.
|
||||
* of compressing multiple emissions of #GtkAdjustment::changed into one.
|
||||
*
|
||||
* Since: 2.14
|
||||
**/
|
||||
@@ -736,7 +736,7 @@ gtk_adjustment_configure (GtkAdjustment *adjustment,
|
||||
*
|
||||
* Emits a #GtkAdjustment::changed signal from the #GtkAdjustment.
|
||||
* This is typically called by the owner of the #GtkAdjustment after it has
|
||||
* changed any of the #GtkAdjustment fields other than the value.
|
||||
* changed any of the #GtkAdjustment properties other than the value.
|
||||
*/
|
||||
void
|
||||
gtk_adjustment_changed (GtkAdjustment *adjustment)
|
||||
@@ -752,7 +752,7 @@ gtk_adjustment_changed (GtkAdjustment *adjustment)
|
||||
*
|
||||
* Emits a #GtkAdjustment::value_changed signal from the #GtkAdjustment.
|
||||
* This is typically called by the owner of the #GtkAdjustment after it has
|
||||
* changed the #GtkAdjustment value field.
|
||||
* changed the #GtkAdjustment:value property.
|
||||
*/
|
||||
void
|
||||
gtk_adjustment_value_changed (GtkAdjustment *adjustment)
|
||||
@@ -769,7 +769,7 @@ gtk_adjustment_value_changed (GtkAdjustment *adjustment)
|
||||
* @lower: the lower value.
|
||||
* @upper: the upper value.
|
||||
*
|
||||
* Updates the #GtkAdjustment #GtkAdjustment:value to ensure that the range
|
||||
* Updates the #GtkAdjustment:value property to ensure that the range
|
||||
* between @lower and @upper is in the current page (i.e. between
|
||||
* #GtkAdjustment:value and #GtkAdjustment:value + #GtkAdjustment:page_size).
|
||||
* If the range is larger than the page size, then only the start of it will
|
||||
|
||||
@@ -185,7 +185,7 @@ app_chooser_online_get_default_ready_cb (GObject *source,
|
||||
GtkWidget *action_area;
|
||||
|
||||
action_area = gtk_dialog_get_action_area (GTK_DIALOG (self));
|
||||
self->priv->online_button = gtk_button_new_with_label (_("Find applications online"));
|
||||
self->priv->online_button = gtk_button_new_with_mnemonic (_("_Find applications online"));
|
||||
gtk_box_pack_start (GTK_BOX (action_area), self->priv->online_button,
|
||||
FALSE, FALSE, 0);
|
||||
gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (action_area), self->priv->online_button,
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
#include "gtkmain.h"
|
||||
#include "gtkrecentmanager.h"
|
||||
#include "gtkaccelmapprivate.h"
|
||||
#include "gactionmuxer.h"
|
||||
#include "gtkintl.h"
|
||||
|
||||
#ifdef GDK_WINDOWING_QUARTZ
|
||||
@@ -132,7 +131,8 @@ enum {
|
||||
PROP_ZERO,
|
||||
PROP_REGISTER_SESSION,
|
||||
PROP_APP_MENU,
|
||||
PROP_MENUBAR
|
||||
PROP_MENUBAR,
|
||||
PROP_ACTIVE_WINDOW
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GtkApplication, gtk_application, G_TYPE_APPLICATION)
|
||||
@@ -166,7 +166,6 @@ struct _GtkApplicationPrivate
|
||||
#endif
|
||||
|
||||
#ifdef GDK_WINDOWING_QUARTZ
|
||||
GActionMuxer *muxer;
|
||||
GMenu *combined;
|
||||
|
||||
GSList *inhibitors;
|
||||
@@ -345,7 +344,9 @@ gtk_application_menu_changed_quartz (GObject *object,
|
||||
g_menu_append_submenu (combined, "Application", gtk_application_get_app_menu (application));
|
||||
g_menu_append_section (combined, NULL, gtk_application_get_menubar (application));
|
||||
|
||||
gtk_quartz_set_main_menu (G_MENU_MODEL (combined), G_ACTION_OBSERVABLE (application->priv->muxer));
|
||||
gtk_quartz_set_main_menu (G_MENU_MODEL (combined), application);
|
||||
|
||||
g_object_unref (combined);
|
||||
}
|
||||
|
||||
static void gtk_application_startup_session_quartz (GtkApplication *app);
|
||||
@@ -355,9 +356,6 @@ gtk_application_startup_quartz (GtkApplication *application)
|
||||
{
|
||||
[NSApp finishLaunching];
|
||||
|
||||
application->priv->muxer = g_action_muxer_new ();
|
||||
g_action_muxer_insert (application->priv->muxer, "app", G_ACTION_GROUP (application));
|
||||
|
||||
g_signal_connect (application, "notify::app-menu", G_CALLBACK (gtk_application_menu_changed_quartz), NULL);
|
||||
g_signal_connect (application, "notify::menubar", G_CALLBACK (gtk_application_menu_changed_quartz), NULL);
|
||||
gtk_application_menu_changed_quartz (G_OBJECT (application), NULL, NULL);
|
||||
@@ -368,25 +366,14 @@ gtk_application_startup_quartz (GtkApplication *application)
|
||||
static void
|
||||
gtk_application_shutdown_quartz (GtkApplication *application)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (application, gtk_application_menu_changed_quartz, NULL);
|
||||
gtk_quartz_clear_main_menu ();
|
||||
|
||||
g_object_unref (application->priv->muxer);
|
||||
application->priv->muxer = NULL;
|
||||
g_signal_handlers_disconnect_by_func (application, gtk_application_menu_changed_quartz, NULL);
|
||||
|
||||
g_slist_free_full (application->priv->inhibitors,
|
||||
(GDestroyNotify) gtk_application_quartz_inhibitor_free);
|
||||
application->priv->inhibitors = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_application_focus_changed (GtkApplication *application,
|
||||
GtkWindow *window)
|
||||
{
|
||||
if (G_IS_ACTION_GROUP (window))
|
||||
g_action_muxer_insert (application->priv->muxer, "win", G_ACTION_GROUP (window));
|
||||
else
|
||||
g_action_muxer_remove (application->priv->muxer, "win");
|
||||
}
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
@@ -405,9 +392,7 @@ gtk_application_focus_in_event_cb (GtkWindow *window,
|
||||
priv->windows = g_list_concat (link, priv->windows);
|
||||
}
|
||||
|
||||
#ifdef GDK_WINDOWING_QUARTZ
|
||||
gtk_application_focus_changed (application, window);
|
||||
#endif
|
||||
g_object_notify (G_OBJECT (application), "active-window");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@@ -529,6 +514,8 @@ gtk_application_window_added (GtkApplication *application,
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
gtk_application_window_added_x11 (application, window);
|
||||
#endif
|
||||
|
||||
g_object_notify (G_OBJECT (application), "active-window");
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -536,6 +523,9 @@ gtk_application_window_removed (GtkApplication *application,
|
||||
GtkWindow *window)
|
||||
{
|
||||
GtkApplicationPrivate *priv = application->priv;
|
||||
gpointer old_active;
|
||||
|
||||
old_active = priv->windows;
|
||||
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
gtk_application_window_removed_x11 (application, window);
|
||||
@@ -548,6 +538,9 @@ gtk_application_window_removed (GtkApplication *application,
|
||||
g_application_release (G_APPLICATION (application));
|
||||
priv->windows = g_list_remove (priv->windows, window);
|
||||
gtk_window_set_application (window, NULL);
|
||||
|
||||
if (priv->windows != old_active)
|
||||
g_object_notify (G_OBJECT (application), "active-window");
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -755,6 +748,13 @@ gtk_application_class_init (GtkApplicationClass *class)
|
||||
P_("The GMenuModel for the menubar"),
|
||||
G_TYPE_MENU_MODEL,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_ACTIVE_WINDOW,
|
||||
g_param_spec_object ("active-window",
|
||||
P_("Active window"),
|
||||
P_("The window which most recently had focus"),
|
||||
GTK_TYPE_WINDOW,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -915,6 +915,29 @@ gtk_application_get_window_by_id (GtkApplication *application,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_application_get_active_window:
|
||||
* @application: a #GtkApplication
|
||||
*
|
||||
* Gets the "active" window for the application.
|
||||
*
|
||||
* The active window is the one that was most recently focused (within
|
||||
* the application). This window may not have the focus at the moment
|
||||
* if another application has it -- this is just the most
|
||||
* recently-focused window within this application.
|
||||
*
|
||||
* Returns: (transfer none): the active window
|
||||
*
|
||||
* Since: 3.6
|
||||
**/
|
||||
GtkWindow *
|
||||
gtk_application_get_active_window (GtkApplication *application)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_APPLICATION (application), NULL);
|
||||
|
||||
return application->priv->windows ? application->priv->windows->data : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_application_add_accelerator:
|
||||
* @application: a #GtkApplication
|
||||
|
||||
@@ -119,6 +119,9 @@ GDK_AVAILABLE_IN_3_6
|
||||
GtkWindow * gtk_application_get_window_by_id (GtkApplication *application,
|
||||
guint id);
|
||||
|
||||
GDK_AVAILABLE_IN_3_6
|
||||
GtkWindow * gtk_application_get_active_window (GtkApplication *application);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_APPLICATION_H__ */
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#ifndef __GTK_APPLICATION_PRIVATE_H__
|
||||
#define __GTK_APPLICATION_PRIVATE_H__
|
||||
|
||||
#include "gsimpleactionobserver.h"
|
||||
#include "gtkapplicationwindow.h"
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
@@ -33,14 +32,6 @@ gboolean gtk_application_window_publish (GtkAppl
|
||||
G_GNUC_INTERNAL
|
||||
void gtk_application_window_unpublish (GtkApplicationWindow *window);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GSimpleActionObserver * gtk_application_window_create_observer (GtkApplicationWindow *window,
|
||||
const gchar *action_name,
|
||||
GVariant *target);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GActionObservable * gtk_application_window_get_observable (GtkApplicationWindow *window);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GtkAccelGroup * gtk_application_window_get_accel_group (GtkApplicationWindow *window);
|
||||
|
||||
|
||||
@@ -22,9 +22,9 @@
|
||||
#include "gtkapplicationwindow.h"
|
||||
|
||||
#include "gtkapplicationprivate.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gtkwindowprivate.h"
|
||||
#include "gtkmodelmenu.h"
|
||||
#include "gactionmuxer.h"
|
||||
#include "gtkaccelgroup.h"
|
||||
#include "gtkaccelmap.h"
|
||||
#include "gtkintl.h"
|
||||
@@ -107,6 +107,14 @@
|
||||
* </programlisting>
|
||||
* </example>
|
||||
*
|
||||
* <example><title>Handling fallback yourself</title>
|
||||
* <programlisting>
|
||||
* <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../examples/sunny.c">
|
||||
* <xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback>
|
||||
* </xi:include>
|
||||
* </programlisting>
|
||||
* </example>
|
||||
*
|
||||
* The XML format understood by #GtkBuilder for #GMenuModel consists
|
||||
* of a toplevel <tag class="starttag">menu</tag> element, which contains
|
||||
* one or more <tag class="starttag">item</tag> elements. Each
|
||||
@@ -205,8 +213,6 @@ gtk_application_window_actions_new (GtkApplicationWindow *window)
|
||||
struct _GtkApplicationWindowPrivate
|
||||
{
|
||||
GSimpleActionGroup *actions;
|
||||
GActionObservable *muxer;
|
||||
gboolean muxer_initialised;
|
||||
GtkWidget *menubar;
|
||||
GtkAccelGroup *accels;
|
||||
GSList *accel_closures;
|
||||
@@ -250,7 +256,7 @@ gtk_application_window_update_menubar (GtkApplicationWindow *window)
|
||||
g_menu_append_section (combined, NULL, G_MENU_MODEL (window->priv->app_menu_section));
|
||||
g_menu_append_section (combined, NULL, G_MENU_MODEL (window->priv->menubar_section));
|
||||
|
||||
window->priv->menubar = gtk_model_menu_create_menu_bar (G_MENU_MODEL (combined), window->priv->muxer, window->priv->accels);
|
||||
window->priv->menubar = gtk_model_menu_create_menu_bar (G_MENU_MODEL (combined), window->priv->accels);
|
||||
gtk_widget_set_parent (window->priv->menubar, GTK_WIDGET (window));
|
||||
gtk_widget_show_all (window->priv->menubar);
|
||||
g_object_unref (combined);
|
||||
@@ -412,11 +418,6 @@ free_accel_closures (GtkApplicationWindow *window)
|
||||
window->priv->accel_closures = NULL;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GtkApplicationWindow *window;
|
||||
GActionGroup *actions;
|
||||
} AccelData;
|
||||
|
||||
/* Hack. We iterate over the accel map instead of the actions,
|
||||
* in order to pull the parameters out of accel map entries
|
||||
*/
|
||||
@@ -427,9 +428,8 @@ add_accel_closure (gpointer data,
|
||||
GdkModifierType accel_mods,
|
||||
gboolean changed)
|
||||
{
|
||||
AccelData *d = data;
|
||||
GtkApplicationWindow *window = d->window;
|
||||
GActionGroup *actions = d->actions;
|
||||
GtkApplicationWindow *window = data;
|
||||
GActionGroup *actions;
|
||||
const gchar *path;
|
||||
const gchar *p;
|
||||
gchar *action_name;
|
||||
@@ -457,6 +457,7 @@ add_accel_closure (gpointer data,
|
||||
parameter = NULL;
|
||||
}
|
||||
|
||||
actions = G_ACTION_GROUP (_gtk_widget_get_action_muxer (GTK_WIDGET (window)));
|
||||
if (g_action_group_has_action (actions, action_name))
|
||||
{
|
||||
closure = (AccelClosure*) g_closure_new_object (sizeof (AccelClosure), g_object_ref (actions));
|
||||
@@ -477,14 +478,9 @@ add_accel_closure (gpointer data,
|
||||
static void
|
||||
gtk_application_window_update_accels (GtkApplicationWindow *window)
|
||||
{
|
||||
AccelData data;
|
||||
|
||||
free_accel_closures (window);
|
||||
|
||||
data.window = window;
|
||||
data.actions = G_ACTION_GROUP (window->priv->muxer);
|
||||
|
||||
gtk_accel_map_foreach (&data, add_accel_closure);
|
||||
gtk_accel_map_foreach (window, add_accel_closure);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -749,13 +745,6 @@ gtk_application_window_real_realize (GtkWidget *widget)
|
||||
g_signal_connect (settings, "notify::gtk-shell-shows-menubar",
|
||||
G_CALLBACK (gtk_application_window_shell_shows_menubar_changed), window);
|
||||
|
||||
if (!window->priv->muxer_initialised)
|
||||
{
|
||||
g_action_muxer_insert (G_ACTION_MUXER (window->priv->muxer), "app", G_ACTION_GROUP (application));
|
||||
g_action_muxer_insert (G_ACTION_MUXER (window->priv->muxer), "win", G_ACTION_GROUP (window));
|
||||
window->priv->muxer_initialised = TRUE;
|
||||
}
|
||||
|
||||
gtk_application_window_update_shell_shows_app_menu (window, settings);
|
||||
gtk_application_window_update_shell_shows_menubar (window, settings);
|
||||
gtk_application_window_update_menubar (window);
|
||||
@@ -878,7 +867,6 @@ gtk_application_window_real_forall_internal (GtkContainer *container,
|
||||
->forall (container, include_internal, callback, user_data);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gtk_application_window_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
@@ -934,7 +922,6 @@ gtk_application_window_dispose (GObject *object)
|
||||
g_clear_object (&window->priv->menubar_section);
|
||||
g_clear_object (&window->priv->actions);
|
||||
g_clear_object (&window->priv->accels);
|
||||
g_clear_object (&window->priv->muxer);
|
||||
|
||||
G_OBJECT_CLASS (gtk_application_window_parent_class)
|
||||
->dispose (object);
|
||||
@@ -951,6 +938,8 @@ gtk_application_window_init (GtkApplicationWindow *window)
|
||||
window->priv->accels = gtk_accel_group_new ();
|
||||
gtk_window_add_accel_group (GTK_WINDOW (window), window->priv->accels);
|
||||
|
||||
gtk_widget_insert_action_group (GTK_WIDGET (window), "win", G_ACTION_GROUP (window->priv->actions));
|
||||
|
||||
/* window->priv->actions is the one and only ref on the group, so when
|
||||
* we dispose, the action group will die, disconnecting all signals.
|
||||
*/
|
||||
@@ -962,8 +951,6 @@ gtk_application_window_init (GtkApplicationWindow *window)
|
||||
G_CALLBACK (g_action_group_action_state_changed), window);
|
||||
g_signal_connect_swapped (window->priv->actions, "action-removed",
|
||||
G_CALLBACK (g_action_group_action_removed), window);
|
||||
|
||||
window->priv->muxer = G_ACTION_OBSERVABLE (g_action_muxer_new ());
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1072,22 +1059,6 @@ gtk_application_window_set_show_menubar (GtkApplicationWindow *window,
|
||||
}
|
||||
}
|
||||
|
||||
GSimpleActionObserver *
|
||||
gtk_application_window_create_observer (GtkApplicationWindow *window,
|
||||
const gchar *action_name,
|
||||
GVariant *target)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_APPLICATION_WINDOW (window), NULL);
|
||||
|
||||
return g_simple_action_observer_new (window->priv->muxer, action_name, target);
|
||||
}
|
||||
|
||||
GActionObservable *
|
||||
gtk_application_window_get_observable (GtkApplicationWindow *window)
|
||||
{
|
||||
return G_ACTION_OBSERVABLE (window->priv->muxer);
|
||||
}
|
||||
|
||||
GtkAccelGroup *
|
||||
gtk_application_window_get_accel_group (GtkApplicationWindow *window)
|
||||
{
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
#include "gtkintl.h"
|
||||
#include "a11y/gtkbuttonaccessible.h"
|
||||
#include "gtkapplicationprivate.h"
|
||||
#include "gtkactionable.h"
|
||||
#include "gtkactionhelper.h"
|
||||
|
||||
static const GtkBorder default_default_border = { 1, 1, 1, 1 };
|
||||
static const GtkBorder default_default_outside_border = { 0, 0, 0, 0 };
|
||||
@@ -151,9 +151,6 @@ static void gtk_button_state_changed (GtkWidget *widget,
|
||||
GtkStateType previous_state);
|
||||
static void gtk_button_grab_notify (GtkWidget *widget,
|
||||
gboolean was_grabbed);
|
||||
static void gtk_button_hierarchy_changed (GtkWidget *widget,
|
||||
GtkWidget *previous_toplevel);
|
||||
|
||||
|
||||
static void gtk_button_actionable_iface_init (GtkActionableInterface *iface);
|
||||
static void gtk_button_activatable_interface_init(GtkActivatableIface *iface);
|
||||
@@ -217,7 +214,6 @@ gtk_button_class_init (GtkButtonClass *klass)
|
||||
widget_class->leave_notify_event = gtk_button_leave_notify;
|
||||
widget_class->state_changed = gtk_button_state_changed;
|
||||
widget_class->grab_notify = gtk_button_grab_notify;
|
||||
widget_class->hierarchy_changed = gtk_button_hierarchy_changed;
|
||||
|
||||
container_class->child_type = gtk_button_child_type;
|
||||
container_class->add = gtk_button_add;
|
||||
@@ -616,12 +612,6 @@ gtk_button_destroy (GtkWidget *widget)
|
||||
priv->label_text = NULL;
|
||||
}
|
||||
|
||||
if (priv->action_name)
|
||||
{
|
||||
g_free (priv->action_name);
|
||||
priv->action_name = NULL;
|
||||
}
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_button_parent_class)->destroy (widget);
|
||||
}
|
||||
|
||||
@@ -704,7 +694,7 @@ gtk_button_dispose (GObject *object)
|
||||
GtkButton *button = GTK_BUTTON (object);
|
||||
GtkButtonPrivate *priv = button->priv;
|
||||
|
||||
g_clear_object (&priv->action_observer);
|
||||
g_clear_object (&priv->action_helper);
|
||||
|
||||
if (priv->action)
|
||||
{
|
||||
@@ -714,53 +704,22 @@ gtk_button_dispose (GObject *object)
|
||||
G_OBJECT_CLASS (gtk_button_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_button_update_action_observer (GtkButton *button)
|
||||
{
|
||||
GtkWidget *window;
|
||||
|
||||
g_signal_handlers_disconnect_by_func (button, gtk_real_button_clicked, NULL);
|
||||
|
||||
/* we are the only owner so this will clear all the signals */
|
||||
g_clear_object (&button->priv->action_observer);
|
||||
|
||||
window = gtk_widget_get_toplevel (GTK_WIDGET (button));
|
||||
|
||||
if (GTK_IS_APPLICATION_WINDOW (window) && button->priv->action_name)
|
||||
{
|
||||
GSimpleActionObserver *observer;
|
||||
|
||||
observer = gtk_application_window_create_observer (GTK_APPLICATION_WINDOW (window),
|
||||
button->priv->action_name,
|
||||
button->priv->action_target);
|
||||
|
||||
_gtk_button_set_depressed (button, g_simple_action_observer_get_active (observer));
|
||||
|
||||
if (g_object_class_find_property (G_OBJECT_GET_CLASS (button), "active"))
|
||||
g_object_bind_property (observer, "active", button, "active", G_BINDING_SYNC_CREATE);
|
||||
g_object_bind_property (observer, "enabled", button, "sensitive", G_BINDING_SYNC_CREATE);
|
||||
|
||||
button->priv->action_observer = observer;
|
||||
|
||||
g_signal_connect_after (button, "clicked", G_CALLBACK (gtk_real_button_clicked), NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_button_set_action_name (GtkActionable *actionable,
|
||||
const gchar *action_name)
|
||||
{
|
||||
GtkButton *button = GTK_BUTTON (actionable);
|
||||
|
||||
g_return_if_fail (GTK_IS_BUTTON (button));
|
||||
g_return_if_fail (button->priv->action == NULL);
|
||||
|
||||
g_free (button->priv->action_name);
|
||||
button->priv->action_name = g_strdup (action_name);
|
||||
if (!button->priv->action_helper)
|
||||
button->priv->action_helper = gtk_action_helper_new (actionable);
|
||||
|
||||
gtk_button_update_action_observer (button);
|
||||
g_signal_handlers_disconnect_by_func (button, gtk_real_button_clicked, NULL);
|
||||
if (action_name)
|
||||
g_signal_connect_after (button, "clicked", G_CALLBACK (gtk_real_button_clicked), NULL);
|
||||
|
||||
g_object_notify (G_OBJECT (button), "action-name");
|
||||
gtk_action_helper_set_action_name (button->priv->action_helper, action_name);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -769,24 +728,10 @@ gtk_button_set_action_target_value (GtkActionable *actionable,
|
||||
{
|
||||
GtkButton *button = GTK_BUTTON (actionable);
|
||||
|
||||
g_return_if_fail (GTK_IS_BUTTON (button));
|
||||
if (!button->priv->action_helper)
|
||||
button->priv->action_helper = gtk_action_helper_new (actionable);
|
||||
|
||||
if (action_target != button->priv->action_target &&
|
||||
(!action_target || !button->priv->action_target ||
|
||||
!g_variant_equal (action_target, button->priv->action_target)))
|
||||
{
|
||||
if (button->priv->action_target)
|
||||
g_variant_unref (button->priv->action_target);
|
||||
|
||||
button->priv->action_target = NULL;
|
||||
|
||||
if (action_target)
|
||||
button->priv->action_target = g_variant_ref_sink (action_target);
|
||||
|
||||
gtk_button_update_action_observer (button);
|
||||
|
||||
g_object_notify (G_OBJECT (button), "action-target");
|
||||
}
|
||||
gtk_action_helper_set_action_target_value (button->priv->action_helper, action_target);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -896,10 +841,10 @@ gtk_button_get_property (GObject *object,
|
||||
g_value_set_boolean (value, priv->use_action_appearance);
|
||||
break;
|
||||
case PROP_ACTION_NAME:
|
||||
g_value_set_string (value, priv->action_name);
|
||||
g_value_set_string (value, gtk_action_helper_get_action_name (priv->action_helper));
|
||||
break;
|
||||
case PROP_ACTION_TARGET:
|
||||
g_value_set_variant (value, priv->action_target);
|
||||
g_value_set_variant (value, gtk_action_helper_get_action_target_value (priv->action_helper));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
@@ -912,7 +857,7 @@ gtk_button_get_action_name (GtkActionable *actionable)
|
||||
{
|
||||
GtkButton *button = GTK_BUTTON (actionable);
|
||||
|
||||
return button->priv->action_name;
|
||||
return gtk_action_helper_get_action_name (button->priv->action_helper);
|
||||
}
|
||||
|
||||
static GVariant *
|
||||
@@ -920,7 +865,7 @@ gtk_button_get_action_target_value (GtkActionable *actionable)
|
||||
{
|
||||
GtkButton *button = GTK_BUTTON (actionable);
|
||||
|
||||
return button->priv->action_target;
|
||||
return gtk_action_helper_get_action_target_value (button->priv->action_helper);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1069,7 +1014,7 @@ gtk_button_set_related_action (GtkButton *button,
|
||||
{
|
||||
GtkButtonPrivate *priv = button->priv;
|
||||
|
||||
g_return_if_fail (button->priv->action_name == NULL);
|
||||
g_return_if_fail (gtk_action_helper_get_action_name (button->priv->action_helper) == NULL);
|
||||
|
||||
if (priv->action == action)
|
||||
return;
|
||||
@@ -2027,8 +1972,8 @@ gtk_real_button_clicked (GtkButton *button)
|
||||
{
|
||||
GtkButtonPrivate *priv = button->priv;
|
||||
|
||||
if (priv->action_observer)
|
||||
g_simple_action_observer_activate (priv->action_observer);
|
||||
if (priv->action_helper)
|
||||
gtk_action_helper_activate (priv->action_helper);
|
||||
|
||||
if (priv->action)
|
||||
gtk_action_activate (priv->action);
|
||||
@@ -2624,28 +2569,6 @@ gtk_button_grab_notify (GtkWidget *widget,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_button_hierarchy_changed (GtkWidget *widget,
|
||||
GtkWidget *previous_toplevel)
|
||||
{
|
||||
GtkButton *button = GTK_BUTTON (widget);
|
||||
GtkWidgetClass *parent_class;
|
||||
|
||||
parent_class = GTK_WIDGET_CLASS (gtk_button_parent_class);
|
||||
if (parent_class->hierarchy_changed)
|
||||
parent_class->hierarchy_changed (widget, previous_toplevel);
|
||||
|
||||
if (button->priv->action_name)
|
||||
{
|
||||
GtkWidget *toplevel;
|
||||
|
||||
toplevel = gtk_widget_get_toplevel (widget);
|
||||
|
||||
if (toplevel != previous_toplevel)
|
||||
gtk_button_update_action_observer (button);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_button_set_image:
|
||||
* @button: a #GtkButton
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#ifndef __GTK_BUTTON_PRIVATE_H__
|
||||
#define __GTK_BUTTON_PRIVATE_H__
|
||||
|
||||
#include "gsimpleactionobserver.h"
|
||||
#include "gtkactionhelper.h"
|
||||
#include "gtkaction.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
@@ -29,10 +29,7 @@ struct _GtkButtonPrivate
|
||||
{
|
||||
GtkAction *action;
|
||||
GtkWidget *image;
|
||||
|
||||
gchar *action_name;
|
||||
GVariant *action_target;
|
||||
GSimpleActionObserver *action_observer;
|
||||
GtkActionHelper *action_helper;
|
||||
|
||||
GdkDevice *grab_keyboard;
|
||||
GdkWindow *event_window;
|
||||
|
||||
@@ -105,12 +105,25 @@ gtk_check_button_class_init (GtkCheckButtonClass *class)
|
||||
GTK_PARAM_READABLE));
|
||||
}
|
||||
|
||||
static void
|
||||
draw_indicator_changed (GObject *object,
|
||||
GParamSpec *pspec,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkButton *button = GTK_BUTTON (object);
|
||||
|
||||
if (gtk_toggle_button_get_mode (GTK_TOGGLE_BUTTON (button)))
|
||||
gtk_button_set_alignment (button, 0.0, 0.5);
|
||||
else
|
||||
gtk_button_set_alignment (button, 0.5, 0.5);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_check_button_init (GtkCheckButton *check_button)
|
||||
{
|
||||
gtk_widget_set_receives_default (GTK_WIDGET (check_button), FALSE);
|
||||
g_signal_connect (check_button, "notify::draw-indicator", G_CALLBACK (draw_indicator_changed), NULL);
|
||||
gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (check_button), TRUE);
|
||||
gtk_button_set_alignment (GTK_BUTTON (check_button), 0.0, 0.5);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -247,6 +247,11 @@ clipboard_display_closed (GdkDisplay *display,
|
||||
g_object_unref (clipboard);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_clipboard_get_for_display:
|
||||
* @display: the display for which the clipboard is to be retrieved or created
|
||||
* @selection: a #GdkAtom which identifies the clipboard to use.
|
||||
*/
|
||||
GtkClipboard *
|
||||
gtk_clipboard_get_for_display (GdkDisplay *display,
|
||||
GdkAtom selection)
|
||||
@@ -257,6 +262,10 @@ gtk_clipboard_get_for_display (GdkDisplay *display,
|
||||
return clipboard_peek (display, selection, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_clipboard_get:
|
||||
* @selection: a #GdkAtom which identifies the clipboard to use
|
||||
*/
|
||||
GtkClipboard *
|
||||
gtk_clipboard_get (GdkAtom selection)
|
||||
{
|
||||
@@ -380,6 +389,18 @@ gtk_clipboard_set_contents (GtkClipboard *clipboard,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_clipboard_set_with_data: (skip)
|
||||
* @clipboard: a #GtkClipboard
|
||||
* @targets: (array length=n_targets): array containing information
|
||||
* about the available forms for the clipboard data
|
||||
* @n_targets: number of elements in @targets
|
||||
* @get_func: (scope async): function to call to get the actual clipboard data
|
||||
* @clear_func: (scope async): when the clipboard contents are set again,
|
||||
* this function will be called, and @get_func will not be subsequently
|
||||
* called.
|
||||
* @user_data: user data to pass to @get_func and @clear_func.
|
||||
*/
|
||||
gboolean
|
||||
gtk_clipboard_set_with_data (GtkClipboard *clipboard,
|
||||
const GtkTargetEntry *targets,
|
||||
@@ -397,6 +418,19 @@ gtk_clipboard_set_with_data (GtkClipboard *clipboard,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_clipboard_set_with_owner: (skip)
|
||||
* @clipboard: a #GtkClipboard
|
||||
* @targets: (array length=n_targets): array containing information
|
||||
* about the available forms for the clipboard data
|
||||
* @n_targets: number of elements in @targets
|
||||
* @get_func: (scope async): function to call to get the actual clipboard data
|
||||
* @clear_func: (scope async): when the clipboard contents are set again,
|
||||
* this function will be called, and @get_func will not be subsequently
|
||||
* called
|
||||
* @owner: an object that "owns" the data. This object will be passed
|
||||
* to the callbacks when called
|
||||
*/
|
||||
gboolean
|
||||
gtk_clipboard_set_with_owner (GtkClipboard *clipboard,
|
||||
const GtkTargetEntry *targets,
|
||||
@@ -415,6 +449,10 @@ gtk_clipboard_set_with_owner (GtkClipboard *clipboard,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_clipboard_get_owner:
|
||||
* @clipboard: a #GtkClipboard
|
||||
*/
|
||||
GObject *
|
||||
gtk_clipboard_get_owner (GtkClipboard *clipboard)
|
||||
{
|
||||
@@ -470,6 +508,10 @@ clipboard_unset (GtkClipboard *clipboard)
|
||||
g_object_unref (old_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_clipboard_clear:
|
||||
* @clipboard: a #GtkClipboard
|
||||
*/
|
||||
void
|
||||
gtk_clipboard_clear (GtkClipboard *clipboard)
|
||||
{
|
||||
@@ -492,6 +534,13 @@ text_clear_func (GtkClipboard *clipboard,
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_clipboard_set_text:
|
||||
* @clipboard: a #GtkClipboard object
|
||||
* @text: a UTF-8 string.
|
||||
* @len: length of @text, in bytes, or -1, in which case
|
||||
* the length will be determined with <function>strlen()</function>.
|
||||
*/
|
||||
void
|
||||
gtk_clipboard_set_text (GtkClipboard *clipboard,
|
||||
const gchar *text,
|
||||
@@ -529,6 +578,11 @@ pixbuf_clear_func (GtkClipboard *clipboard,
|
||||
g_object_unref (data);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_clipboard_set_image:
|
||||
* @clipboard: a #GtkClipboard object
|
||||
* @pixbuf: a #GdkPixbuf
|
||||
*/
|
||||
void
|
||||
gtk_clipboard_set_image (GtkClipboard *clipboard,
|
||||
GdkPixbuf *pixbuf)
|
||||
@@ -564,6 +618,16 @@ gtk_clipboard_set_image (GtkClipboard *clipboard,
|
||||
gtk_target_list_unref (list);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_clipboard_request_contents:
|
||||
* @clipboard: a #GtkClipboard
|
||||
* @target: an atom representing the form into which the clipboard
|
||||
* owner should convert the selection.
|
||||
* @callback: (scope async): A function to call when the results are received
|
||||
* (or the retrieval fails). If the retrieval fails the length field of
|
||||
* @selection_data will be negative.
|
||||
* @user_data: user data to pass to @callback
|
||||
*/
|
||||
void
|
||||
gtk_clipboard_request_contents (GtkClipboard *clipboard,
|
||||
GdkAtom target,
|
||||
@@ -579,6 +643,13 @@ gtk_clipboard_request_contents (GtkClipboard *clipboard,
|
||||
gtk_selection_data_free (data);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_clipboard_request_text:
|
||||
* @clipboard: a #GtkClipboard
|
||||
* @callback: (scope async): a function to call when the text is received,
|
||||
* or the retrieval fails. (It will always be called one way or the other.)
|
||||
* @user_data: user data to pass to @callback.
|
||||
*/
|
||||
void
|
||||
gtk_clipboard_request_text (GtkClipboard *clipboard,
|
||||
GtkClipboardTextReceivedFunc callback,
|
||||
@@ -591,6 +662,14 @@ gtk_clipboard_request_text (GtkClipboard *clipboard,
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_clipboard_request_rich_text:
|
||||
* @clipboard: a #GtkClipboard
|
||||
* @buffer: a #GtkTextBuffer
|
||||
* @callback: (scope async): a function to call when the text is received,
|
||||
* or the retrieval fails. (It will always be called one way or the other.)
|
||||
* @user_data: user data to pass to @callback.
|
||||
*/
|
||||
void
|
||||
gtk_clipboard_request_rich_text (GtkClipboard *clipboard,
|
||||
GtkTextBuffer *buffer,
|
||||
@@ -611,6 +690,13 @@ gtk_clipboard_wait_for_rich_text (GtkClipboard *clipboard,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_clipboard_request_image:
|
||||
* @clipboard: a #GtkClipboard
|
||||
* @callback: (scope async): a function to call when the image is received,
|
||||
* or the retrieval fails. (It will always be called one way or the other.)
|
||||
* @user_data: user data to pass to @callback.
|
||||
*/
|
||||
void
|
||||
gtk_clipboard_request_image (GtkClipboard *clipboard,
|
||||
GtkClipboardImageReceivedFunc callback,
|
||||
@@ -624,6 +710,13 @@ gtk_clipboard_request_image (GtkClipboard *clipboard,
|
||||
g_object_unref (pixbuf);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_clipboard_request_uris:
|
||||
* @clipboard: a #GtkClipboard
|
||||
* @callback: (scope async): a function to call when the URIs are received,
|
||||
* or the retrieval fails. (It will always be called one way or the other.)
|
||||
* @user_data: user data to pass to @callback.
|
||||
*/
|
||||
void
|
||||
gtk_clipboard_request_uris (GtkClipboard *clipboard,
|
||||
GtkClipboardURIReceivedFunc callback,
|
||||
@@ -636,6 +729,14 @@ gtk_clipboard_request_uris (GtkClipboard *clipboard,
|
||||
g_strfreev (uris);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_clipboard_request_targets:
|
||||
* @clipboard: a #GtkClipboard
|
||||
* @callback: (scope async): a function to call when the targets are
|
||||
* received, or the retrieval fails. (It will always be called
|
||||
* one way or the other.)
|
||||
* @user_data: user data to pass to @callback.
|
||||
*/
|
||||
void
|
||||
gtk_clipboard_request_targets (GtkClipboard *clipboard,
|
||||
GtkClipboardTargetsReceivedFunc callback,
|
||||
@@ -650,6 +751,12 @@ gtk_clipboard_request_targets (GtkClipboard *clipboard,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gtk_clipboard_wait_for_contents:
|
||||
* @clipboard: a #GtkClipboard
|
||||
* @target: an atom representing the form into which the clipboard
|
||||
* owner should convert the selection.
|
||||
*/
|
||||
GtkSelectionData *
|
||||
gtk_clipboard_wait_for_contents (GtkClipboard *clipboard,
|
||||
GdkAtom target)
|
||||
@@ -695,6 +802,10 @@ gtk_clipboard_wait_for_contents (GtkClipboard *clipboard,
|
||||
return selection_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_clipboard_wait_for_text:
|
||||
* @clipboard: a #GtkClipboard
|
||||
*/
|
||||
gchar *
|
||||
gtk_clipboard_wait_for_text (GtkClipboard *clipboard)
|
||||
{
|
||||
@@ -711,6 +822,10 @@ gtk_clipboard_wait_for_text (GtkClipboard *clipboard)
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_clipboard_wait_for_image:
|
||||
* @clipboard: a #GtkClipboard
|
||||
*/
|
||||
GdkPixbuf *
|
||||
gtk_clipboard_wait_for_image (GtkClipboard *clipboard)
|
||||
{
|
||||
@@ -735,6 +850,10 @@ gtk_clipboard_wait_for_image (GtkClipboard *clipboard)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_clipboard_wait_for_uris:
|
||||
* @clipboard: a #GtkClipboard
|
||||
*/
|
||||
gchar **
|
||||
gtk_clipboard_wait_for_uris (GtkClipboard *clipboard)
|
||||
{
|
||||
@@ -754,6 +873,10 @@ gtk_clipboard_wait_for_uris (GtkClipboard *clipboard)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_clipboard_get_display:
|
||||
* @clipboard: a #GtkClipboard
|
||||
*/
|
||||
GdkDisplay *
|
||||
gtk_clipboard_get_display (GtkClipboard *clipboard)
|
||||
{
|
||||
@@ -762,6 +885,10 @@ gtk_clipboard_get_display (GtkClipboard *clipboard)
|
||||
return clipboard->display;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_clipboard_wait_is_text_available:
|
||||
* @clipboard: a #GtkClipboard
|
||||
*/
|
||||
gboolean
|
||||
gtk_clipboard_wait_is_text_available (GtkClipboard *clipboard)
|
||||
{
|
||||
@@ -778,6 +905,11 @@ gtk_clipboard_wait_is_text_available (GtkClipboard *clipboard)
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_clipboard_wait_is_rich_text_available:
|
||||
* @clipboard: a #GtkClipboard
|
||||
* @buffer: a #GtkTextBuffer
|
||||
*/
|
||||
gboolean
|
||||
gtk_clipboard_wait_is_rich_text_available (GtkClipboard *clipboard,
|
||||
GtkTextBuffer *buffer)
|
||||
@@ -798,6 +930,10 @@ gtk_clipboard_wait_is_rich_text_available (GtkClipboard *clipboard,
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_clipboard_wait_is_image_available:
|
||||
* @clipboard: a #GtkClipboard
|
||||
*/
|
||||
gboolean
|
||||
gtk_clipboard_wait_is_image_available (GtkClipboard *clipboard)
|
||||
{
|
||||
@@ -815,6 +951,10 @@ gtk_clipboard_wait_is_image_available (GtkClipboard *clipboard)
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_clipboard_wait_is_uris_available:
|
||||
* @clipboard: a #GtkClipboard
|
||||
*/
|
||||
gboolean
|
||||
gtk_clipboard_wait_is_uris_available (GtkClipboard *clipboard)
|
||||
{
|
||||
@@ -832,6 +972,14 @@ gtk_clipboard_wait_is_uris_available (GtkClipboard *clipboard)
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_clipboard_wait_for_targets:
|
||||
* @clipboard: a #GtkClipboard
|
||||
* @targets: (out) (array length=n_targets) (transfer container): location
|
||||
* to store an array of targets. The result stored here must
|
||||
* be freed with g_free().
|
||||
* @n_targets: location to store number of items in @targets.
|
||||
*/
|
||||
gboolean
|
||||
gtk_clipboard_wait_for_targets (GtkClipboard *clipboard,
|
||||
GdkAtom **targets,
|
||||
@@ -962,6 +1110,11 @@ gtk_clipboard_owner_change (GtkClipboard *clipboard,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_clipboard_wait_is_target_available:
|
||||
* @clipboard: a #GtkClipboard
|
||||
* @target: A #GdkAtom indicating which target to look for.
|
||||
*/
|
||||
gboolean
|
||||
gtk_clipboard_wait_is_target_available (GtkClipboard *clipboard,
|
||||
GdkAtom target)
|
||||
@@ -987,11 +1140,23 @@ gtk_clipboard_wait_is_target_available (GtkClipboard *clipboard,
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* _gtk_clipboard_handle_event:
|
||||
* @event: a owner change event
|
||||
*/
|
||||
void
|
||||
_gtk_clipboard_handle_event (GdkEventOwnerChange *event)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_clipboard_set_can_store:
|
||||
* @clipboard: a #GtkClipboard
|
||||
* @targets: (allow-none) (array length=n_targets): array containing
|
||||
* information about which forms should be stored or %NULL
|
||||
* to indicate that all forms should be stored.
|
||||
* @n_targets: number of elements in @targets
|
||||
*/
|
||||
void
|
||||
gtk_clipboard_set_can_store (GtkClipboard *clipboard,
|
||||
const GtkTargetEntry *targets,
|
||||
@@ -1000,6 +1165,10 @@ gtk_clipboard_set_can_store (GtkClipboard *clipboard,
|
||||
/* FIXME: Implement */
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_clipboard_store:
|
||||
* @clipboard: a #GtkClipboard
|
||||
*/
|
||||
void
|
||||
gtk_clipboard_store (GtkClipboard *clipboard)
|
||||
{
|
||||
|
||||
@@ -48,6 +48,8 @@ struct _GtkClipboard
|
||||
GObject *owner;
|
||||
GdkDisplay *display;
|
||||
|
||||
GdkAtom selection;
|
||||
|
||||
SetContentClosure *last_closure;
|
||||
};
|
||||
|
||||
@@ -122,36 +124,70 @@ gtk_clipboard_finalize (GObject *object)
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
GtkClipboard *
|
||||
gtk_clipboard_get_for_display (GdkDisplay *display,
|
||||
GdkAtom selection)
|
||||
static void
|
||||
clipboard_display_closed (GdkDisplay *display,
|
||||
gboolean is_error,
|
||||
GtkClipboard *clipboard)
|
||||
{
|
||||
GtkClipboard *clipboard;
|
||||
GSList *clipboards;
|
||||
|
||||
clipboards = g_object_get_data (G_OBJECT (display), "gtk-clipboard-list");
|
||||
g_object_run_dispose (G_OBJECT (clipboard));
|
||||
clipboards = g_slist_remove (clipboards, clipboard);
|
||||
g_object_set_data (G_OBJECT (display), I_("gtk-clipboard-list"), clipboards);
|
||||
g_object_unref (clipboard);
|
||||
}
|
||||
|
||||
static GtkClipboard *
|
||||
clipboard_peek (GdkDisplay *display,
|
||||
GdkAtom selection,
|
||||
gboolean only_if_exists)
|
||||
{
|
||||
GtkClipboard *clipboard = NULL;
|
||||
GSList *clipboards;
|
||||
GSList *tmp_list;
|
||||
|
||||
if (selection == GDK_NONE)
|
||||
selection = GDK_SELECTION_CLIPBOARD;
|
||||
|
||||
if (selection != GDK_SELECTION_CLIPBOARD)
|
||||
clipboards = g_object_get_data (G_OBJECT (display), "gtk-clipboard-list");
|
||||
|
||||
tmp_list = clipboards;
|
||||
while (tmp_list)
|
||||
{
|
||||
g_warning (G_STRLOC ": Only able to create clipboard for CLIPBOARD");
|
||||
clipboard = tmp_list->data;
|
||||
if (clipboard->selection == selection)
|
||||
break;
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
|
||||
selection = GDK_SELECTION_CLIPBOARD;
|
||||
if (!tmp_list && !only_if_exists)
|
||||
{
|
||||
clipboard = g_object_new (GTK_TYPE_CLIPBOARD, NULL);
|
||||
clipboard->selection = selection;
|
||||
clipboard->display = display;
|
||||
|
||||
clipboard = g_object_get_data (G_OBJECT (display), "gtk-clipboard");
|
||||
|
||||
if (clipboard)
|
||||
return clipboard;
|
||||
|
||||
clipboard = g_object_new (GTK_TYPE_CLIPBOARD, NULL);
|
||||
clipboard->display = display;
|
||||
|
||||
g_object_set_data (G_OBJECT (display), "gtk-clipboard", clipboard);
|
||||
|
||||
/* TODO: Need to connect to display closed to free this */
|
||||
clipboards = g_slist_prepend (clipboards, clipboard);
|
||||
g_object_set_data (G_OBJECT (display), I_("gtk-clipboard-list"), clipboards);
|
||||
g_signal_connect (display, "closed",
|
||||
G_CALLBACK (clipboard_display_closed), clipboard);
|
||||
gdk_display_request_selection_notification (display, selection);
|
||||
}
|
||||
|
||||
return clipboard;
|
||||
}
|
||||
|
||||
GtkClipboard *
|
||||
gtk_clipboard_get_for_display (GdkDisplay *display,
|
||||
GdkAtom selection)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
|
||||
g_return_val_if_fail (!gdk_display_is_closed (display), NULL);
|
||||
|
||||
return clipboard_peek (display, selection, FALSE);
|
||||
}
|
||||
|
||||
GtkClipboard *
|
||||
gtk_clipboard_get (GdkAtom selection)
|
||||
{
|
||||
@@ -164,6 +200,7 @@ struct _SetContentClosure {
|
||||
GtkClipboardGetFunc get_func;
|
||||
GtkClipboardClearFunc clear_func;
|
||||
guint info;
|
||||
gboolean have_owner;
|
||||
gpointer userdata;
|
||||
GtkTargetPair *targets;
|
||||
gint n_targets;
|
||||
@@ -203,6 +240,21 @@ _offer_cb (GdkDevice *device,
|
||||
return (gchar *)selection_data.data;
|
||||
}
|
||||
|
||||
static void
|
||||
clipboard_owner_destroyed (gpointer data,
|
||||
GObject *owner)
|
||||
{
|
||||
GtkClipboard *clipboard = (GtkClipboard *) data;
|
||||
SetContentClosure *last_closure = clipboard->last_closure;
|
||||
|
||||
last_closure->userdata = NULL;
|
||||
last_closure->get_func = NULL;
|
||||
last_closure->clear_func = NULL;
|
||||
last_closure->have_owner = FALSE;
|
||||
|
||||
gtk_clipboard_clear (clipboard);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_clipboard_set_contents (GtkClipboard *clipboard,
|
||||
const GtkTargetEntry *targets,
|
||||
@@ -216,21 +268,34 @@ gtk_clipboard_set_contents (GtkClipboard *clipboard,
|
||||
GdkDevice *device;
|
||||
gint i;
|
||||
gchar **mimetypes;
|
||||
SetContentClosure *closure;
|
||||
SetContentClosure *closure, *last_closure;
|
||||
|
||||
gtk_clipboard_clear (clipboard);
|
||||
last_closure = clipboard->last_closure;
|
||||
if (!last_closure ||
|
||||
(!last_closure->have_owner && have_owner) ||
|
||||
(last_closure->userdata != user_data)) {
|
||||
gtk_clipboard_clear (clipboard);
|
||||
|
||||
closure = g_new0 (SetContentClosure, 1);
|
||||
closure->clipboard = clipboard;
|
||||
closure->userdata = user_data;
|
||||
closure->have_owner = have_owner;
|
||||
|
||||
if (have_owner)
|
||||
g_object_weak_ref (G_OBJECT (user_data), clipboard_owner_destroyed, clipboard);
|
||||
} else {
|
||||
closure = last_closure;
|
||||
g_free (closure->targets);
|
||||
}
|
||||
|
||||
closure->get_func = get_func;
|
||||
closure->clear_func = clear_func;
|
||||
closure->targets = g_new0 (GtkTargetPair, n_targets);
|
||||
closure->n_targets = n_targets;
|
||||
|
||||
device_manager = gdk_display_get_device_manager (gdk_display_get_default ());
|
||||
device = gdk_device_manager_get_client_pointer (device_manager);
|
||||
|
||||
closure = g_new0 (SetContentClosure, 1);
|
||||
closure->clipboard = clipboard;
|
||||
closure->get_func = get_func;
|
||||
closure->clear_func = clear_func;
|
||||
closure->userdata = user_data;
|
||||
closure->targets = g_new0 (GtkTargetPair, n_targets);
|
||||
closure->n_targets = n_targets;
|
||||
|
||||
mimetypes = g_new (gchar *, n_targets);
|
||||
|
||||
for (i = 0; i < n_targets; i++)
|
||||
@@ -318,7 +383,12 @@ gtk_clipboard_clear (GtkClipboard *clipboard)
|
||||
clipboard->last_closure->userdata);
|
||||
}
|
||||
|
||||
/* TODO: Free last closure */
|
||||
if (clipboard->last_closure->have_owner)
|
||||
g_object_weak_unref (G_OBJECT (clipboard->last_closure->userdata),
|
||||
clipboard_owner_destroyed, clipboard);
|
||||
g_free (clipboard->last_closure->targets);
|
||||
g_free (clipboard->last_closure);
|
||||
|
||||
clipboard->last_closure = NULL;
|
||||
}
|
||||
|
||||
@@ -604,9 +674,9 @@ gtk_clipboard_wait_for_contents (GtkClipboard *clipboard,
|
||||
|
||||
if (g_main_loop_is_running (closure->loop))
|
||||
{
|
||||
GDK_THREADS_LEAVE ();
|
||||
gdk_threads_leave ();
|
||||
g_main_loop_run (closure->loop);
|
||||
GDK_THREADS_ENTER ();
|
||||
gdk_threads_enter ();
|
||||
}
|
||||
|
||||
g_main_loop_unref (closure->loop);
|
||||
|
||||
@@ -1410,9 +1410,9 @@ gtk_clipboard_wait_for_contents (GtkClipboard *clipboard,
|
||||
|
||||
if (g_main_loop_is_running (results.loop))
|
||||
{
|
||||
GDK_THREADS_LEAVE ();
|
||||
gdk_threads_leave ();
|
||||
g_main_loop_run (results.loop);
|
||||
GDK_THREADS_ENTER ();
|
||||
gdk_threads_enter ();
|
||||
}
|
||||
|
||||
g_main_loop_unref (results.loop);
|
||||
@@ -1463,9 +1463,9 @@ gtk_clipboard_wait_for_text (GtkClipboard *clipboard)
|
||||
|
||||
if (g_main_loop_is_running (results.loop))
|
||||
{
|
||||
GDK_THREADS_LEAVE ();
|
||||
gdk_threads_leave ();
|
||||
g_main_loop_run (results.loop);
|
||||
GDK_THREADS_ENTER ();
|
||||
gdk_threads_enter ();
|
||||
}
|
||||
|
||||
g_main_loop_unref (results.loop);
|
||||
@@ -1531,9 +1531,9 @@ gtk_clipboard_wait_for_rich_text (GtkClipboard *clipboard,
|
||||
|
||||
if (g_main_loop_is_running (results.loop))
|
||||
{
|
||||
GDK_THREADS_LEAVE ();
|
||||
gdk_threads_leave ();
|
||||
g_main_loop_run (results.loop);
|
||||
GDK_THREADS_ENTER ();
|
||||
gdk_threads_enter ();
|
||||
}
|
||||
|
||||
g_main_loop_unref (results.loop);
|
||||
@@ -1591,9 +1591,9 @@ gtk_clipboard_wait_for_image (GtkClipboard *clipboard)
|
||||
|
||||
if (g_main_loop_is_running (results.loop))
|
||||
{
|
||||
GDK_THREADS_LEAVE ();
|
||||
gdk_threads_leave ();
|
||||
g_main_loop_run (results.loop);
|
||||
GDK_THREADS_ENTER ();
|
||||
gdk_threads_enter ();
|
||||
}
|
||||
|
||||
g_main_loop_unref (results.loop);
|
||||
@@ -1646,9 +1646,9 @@ gtk_clipboard_wait_for_uris (GtkClipboard *clipboard)
|
||||
|
||||
if (g_main_loop_is_running (results.loop))
|
||||
{
|
||||
GDK_THREADS_LEAVE ();
|
||||
gdk_threads_leave ();
|
||||
g_main_loop_run (results.loop);
|
||||
GDK_THREADS_ENTER ();
|
||||
gdk_threads_enter ();
|
||||
}
|
||||
|
||||
g_main_loop_unref (results.loop);
|
||||
@@ -2132,9 +2132,9 @@ gtk_clipboard_store (GtkClipboard *clipboard)
|
||||
|
||||
if (g_main_loop_is_running (clipboard->store_loop))
|
||||
{
|
||||
GDK_THREADS_LEAVE ();
|
||||
gdk_threads_leave ();
|
||||
g_main_loop_run (clipboard->store_loop);
|
||||
GDK_THREADS_ENTER ();
|
||||
gdk_threads_enter ();
|
||||
}
|
||||
|
||||
g_main_loop_unref (clipboard->store_loop);
|
||||
|
||||
@@ -241,8 +241,7 @@ gtk_color_button_class_init (GtkColorButtonClass *klass)
|
||||
* @widget: the object which received the signal.
|
||||
*
|
||||
* The ::color-set signal is emitted when the user selects a color.
|
||||
* When handling this signal, use gtk_color_button_get_color() and
|
||||
* gtk_color_button_get_alpha() (or gtk_color_button_get_rgba()) to
|
||||
* When handling this signal, use gtk_color_button_get_rgba() to
|
||||
* find out which color was just selected.
|
||||
*
|
||||
* Note that this signal is only emitted when the <emphasis>user</emphasis>
|
||||
|
||||
@@ -1648,14 +1648,18 @@ gtk_container_idle_sizer (gpointer data)
|
||||
current_time = g_get_monotonic_time ();
|
||||
slist = container_restyle_queue;
|
||||
container_restyle_queue = NULL;
|
||||
for (; slist; slist = slist->next)
|
||||
while (slist)
|
||||
{
|
||||
GSList *next = slist->next;
|
||||
GtkContainer *container = slist->data;
|
||||
|
||||
container->priv->restyle_pending = FALSE;
|
||||
_gtk_style_context_validate (gtk_widget_get_style_context (GTK_WIDGET (container)),
|
||||
current_time,
|
||||
0);
|
||||
|
||||
g_slist_free_1 (slist);
|
||||
slist = next;
|
||||
}
|
||||
|
||||
/* we may be invoked with a container_resize_queue of NULL, because
|
||||
|
||||
@@ -1106,9 +1106,9 @@ gtk_dialog_run (GtkDialog *dialog)
|
||||
|
||||
ri.loop = g_main_loop_new (NULL, FALSE);
|
||||
|
||||
GDK_THREADS_LEAVE ();
|
||||
gdk_threads_leave ();
|
||||
g_main_loop_run (ri.loop);
|
||||
GDK_THREADS_ENTER ();
|
||||
gdk_threads_enter ();
|
||||
|
||||
g_main_loop_unref (ri.loop);
|
||||
|
||||
|
||||
@@ -177,6 +177,16 @@ struct _GtkDragFindData
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
* gtk_drag_get_data: (method)
|
||||
* @widget: the widget that will receive the
|
||||
* #GtkWidget::drag-data-received signal.
|
||||
* @context: the drag context
|
||||
* @target: the target (form of the data) to retrieve.
|
||||
* @time_: a timestamp for retrieving the data. This will
|
||||
* generally be the time received in a #GtkWidget::drag-motion"
|
||||
* or #GtkWidget::drag-drop" signal.
|
||||
*/
|
||||
void
|
||||
gtk_drag_get_data (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
@@ -233,6 +243,14 @@ gtk_drag_get_data (GtkWidget *widget,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_drag_finish: (method)
|
||||
* @context: the drag context.
|
||||
* @success: a flag indicating whether the drop was successful
|
||||
* @del: a flag indicating whether the source should delete the
|
||||
* original data. (This should be %TRUE for a move)
|
||||
* @time_: the timestamp from the #GtkWidget::drag-drop signal.
|
||||
*/
|
||||
void
|
||||
gtk_drag_finish (GdkDragContext *context,
|
||||
gboolean success,
|
||||
@@ -312,6 +330,10 @@ gtk_drag_clear_source_info (GdkDragContext *context)
|
||||
g_object_set_qdata (G_OBJECT (context), dest_info_quark, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_drag_get_source_widget: (method)
|
||||
* @context: a (destination side) drag context
|
||||
*/
|
||||
GtkWidget *
|
||||
gtk_drag_get_source_widget (GdkDragContext *context)
|
||||
{
|
||||
@@ -364,14 +386,10 @@ gtk_drag_highlight_draw (GtkWidget *widget,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* gtk_drag_highlight:
|
||||
* Highlight the given widget in the default manner.
|
||||
* arguments:
|
||||
* widget:
|
||||
* results:
|
||||
*************************************************************/
|
||||
|
||||
/**
|
||||
* gtk_drag_highlight: (method)
|
||||
* @widget: a widget to highlight
|
||||
*/
|
||||
void
|
||||
gtk_drag_highlight (GtkWidget *widget)
|
||||
{
|
||||
@@ -384,14 +402,10 @@ gtk_drag_highlight (GtkWidget *widget)
|
||||
gtk_widget_queue_draw (widget);
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* gtk_drag_unhighlight:
|
||||
* Refresh the given widget to remove the highlight.
|
||||
* arguments:
|
||||
* widget:
|
||||
* results:
|
||||
*************************************************************/
|
||||
|
||||
/**
|
||||
* gtk_drag_unhighlight: (method)
|
||||
* @widget: a widget to remove the highlight from.
|
||||
*/
|
||||
void
|
||||
gtk_drag_unhighlight (GtkWidget *widget)
|
||||
{
|
||||
@@ -468,6 +482,17 @@ gtk_drag_dest_site_destroy (gpointer data)
|
||||
g_free (site);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_drag_dest_set: (method)
|
||||
* @widget: a #GtkWidget
|
||||
* @flags: which types of default drag behavior to use
|
||||
* @targets: (allow-none) (array length=n_targets): a pointer to an array of #GtkTargetEntry<!-- -->s
|
||||
* indicating the drop types that this @widget will accept, or %NULL.
|
||||
* Later you can access the list with gtk_drag_dest_get_target_list()
|
||||
* and gtk_drag_dest_find_target().
|
||||
* @n_targets: the number of entries in @targets
|
||||
* @actions: a bitmask of possible actions for a drop onto this @widget.
|
||||
*/
|
||||
void
|
||||
gtk_drag_dest_set (GtkWidget *widget,
|
||||
GtkDestDefaults flags,
|
||||
@@ -509,6 +534,16 @@ gtk_drag_dest_set (GtkWidget *widget,
|
||||
site, gtk_drag_dest_site_destroy);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_drag_dest_set_proxy: (method)
|
||||
* @widget: a #GtkWidget
|
||||
* @proxy_window: the window to which to forward drag events
|
||||
* @protocol: the drag protocol which the @proxy_window accepts
|
||||
* (You can use gdk_drag_get_protocol() to determine this)
|
||||
* @use_coordinates: If %TRUE, send the same coordinates to the
|
||||
* destination, because it is an embedded
|
||||
* subwindow.
|
||||
*/
|
||||
void
|
||||
gtk_drag_dest_set_proxy (GtkWidget *widget,
|
||||
GdkWindow *proxy_window,
|
||||
@@ -518,6 +553,10 @@ gtk_drag_dest_set_proxy (GtkWidget *widget,
|
||||
g_warning ("gtk_drag_dest_set_proxy is not supported on Mac OS X.");
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_drag_dest_unset: (method)
|
||||
* @widget: a #GtkWidget
|
||||
*/
|
||||
void
|
||||
gtk_drag_dest_unset (GtkWidget *widget)
|
||||
{
|
||||
@@ -539,6 +578,10 @@ gtk_drag_dest_unset (GtkWidget *widget)
|
||||
g_object_set_data (G_OBJECT (widget), I_("gtk-drag-dest"), NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_drag_dest_get_target_list: (method)
|
||||
* @widget: a #GtkWidget
|
||||
*/
|
||||
GtkTargetList*
|
||||
gtk_drag_dest_get_target_list (GtkWidget *widget)
|
||||
{
|
||||
@@ -551,6 +594,11 @@ gtk_drag_dest_get_target_list (GtkWidget *widget)
|
||||
return site ? site->target_list : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_drag_dest_set_target_list: (method)
|
||||
* @widget: a #GtkWidget that's a drag destination
|
||||
* @target_list: (allow-none): list of droppable targets, or %NULL for none
|
||||
*/
|
||||
void
|
||||
gtk_drag_dest_set_target_list (GtkWidget *widget,
|
||||
GtkTargetList *target_list)
|
||||
@@ -579,6 +627,10 @@ gtk_drag_dest_set_target_list (GtkWidget *widget,
|
||||
register_types (widget, site);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_drag_dest_add_text_targets: (method)
|
||||
* @widget: a #GtkWidget that's a drag destination
|
||||
*/
|
||||
void
|
||||
gtk_drag_dest_add_text_targets (GtkWidget *widget)
|
||||
{
|
||||
@@ -594,6 +646,11 @@ gtk_drag_dest_add_text_targets (GtkWidget *widget)
|
||||
gtk_target_list_unref (target_list);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gtk_drag_dest_add_image_targets: (method)
|
||||
* @widget: a #GtkWidget that's a drag destination
|
||||
*/
|
||||
void
|
||||
gtk_drag_dest_add_image_targets (GtkWidget *widget)
|
||||
{
|
||||
@@ -609,6 +666,10 @@ gtk_drag_dest_add_image_targets (GtkWidget *widget)
|
||||
gtk_target_list_unref (target_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_drag_dest_add_uri_targets: (method)
|
||||
* @widget: a #GtkWidget that's a drag destination
|
||||
*/
|
||||
void
|
||||
gtk_drag_dest_add_uri_targets (GtkWidget *widget)
|
||||
{
|
||||
@@ -876,6 +937,11 @@ gtk_drag_dest_drop (GtkWidget *widget,
|
||||
return (site->flags & GTK_DEST_DEFAULT_DROP) ? TRUE : retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_drag_dest_set_track_motion: (method)
|
||||
* @widget: a #GtkWidget that's a drag destination
|
||||
* @track_motion: whether to accept all targets
|
||||
*/
|
||||
void
|
||||
gtk_drag_dest_set_track_motion (GtkWidget *widget,
|
||||
gboolean track_motion)
|
||||
@@ -891,6 +957,10 @@ gtk_drag_dest_set_track_motion (GtkWidget *widget,
|
||||
site->track_motion = track_motion != FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_drag_dest_get_track_motion: (method)
|
||||
* @widget: a #GtkWidget that's a drag destination
|
||||
*/
|
||||
gboolean
|
||||
gtk_drag_dest_get_track_motion (GtkWidget *widget)
|
||||
{
|
||||
@@ -989,6 +1059,13 @@ _gtk_drag_dest_handle_event (GtkWidget *toplevel,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gtk_drag_dest_find_target: (method)
|
||||
* @widget: drag destination widget
|
||||
* @context: drag context
|
||||
* @target_list: (allow-none): list of droppable targets, or %NULL to use
|
||||
* gtk_drag_dest_get_target_list (@widget).
|
||||
*/
|
||||
GdkAtom
|
||||
gtk_drag_dest_find_target (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
@@ -1231,6 +1308,15 @@ gtk_drag_begin_internal (GtkWidget *widget,
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_drag_begin: (method)
|
||||
* @widget: the source widget.
|
||||
* @targets: The targets (data formats) in which the
|
||||
* source can provide the data.
|
||||
* @actions: A bitmask of the allowed drag actions for this drag.
|
||||
* @button: The button the user clicked to start the drag.
|
||||
* @event: The event that triggered the start of the drag.
|
||||
*/
|
||||
GdkDragContext *
|
||||
gtk_drag_begin (GtkWidget *widget,
|
||||
GtkTargetList *targets,
|
||||
@@ -1306,6 +1392,15 @@ gtk_drag_source_event_cb (GtkWidget *widget,
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_drag_source_set: (method)
|
||||
* @widget: a #GtkWidget
|
||||
* @start_button_mask: the bitmask of buttons that can start the drag
|
||||
* @targets: (allow-none) (array length=n_targets): the table of targets that the drag will support,
|
||||
* may be %NULL
|
||||
* @n_targets: the number of items in @targets
|
||||
* @actions: the bitmask of possible actions for a drag from this widget
|
||||
*/
|
||||
void
|
||||
gtk_drag_source_set (GtkWidget *widget,
|
||||
GdkModifierType start_button_mask,
|
||||
@@ -1357,14 +1452,10 @@ gtk_drag_source_set (GtkWidget *widget,
|
||||
site->actions = actions;
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* gtk_drag_source_unset
|
||||
* Unregister this widget as a drag source.
|
||||
* arguments:
|
||||
* widget:
|
||||
* results:
|
||||
*************************************************************/
|
||||
|
||||
/**
|
||||
* gtk_drag_source_unset: (method)
|
||||
* @widget: a #GtkWidget
|
||||
*/
|
||||
void
|
||||
gtk_drag_source_unset (GtkWidget *widget)
|
||||
{
|
||||
@@ -1383,6 +1474,10 @@ gtk_drag_source_unset (GtkWidget *widget)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_drag_source_get_target_list: (method)
|
||||
* @widget: a #GtkWidget
|
||||
*/
|
||||
GtkTargetList *
|
||||
gtk_drag_source_get_target_list (GtkWidget *widget)
|
||||
{
|
||||
@@ -1396,6 +1491,11 @@ gtk_drag_source_get_target_list (GtkWidget *widget)
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_drag_source_set_target_list: (method)
|
||||
* @widget: a #GtkWidget that's a drag source
|
||||
* @target_list: (allow-none): list of draggable targets, or %NULL for none
|
||||
*/
|
||||
void
|
||||
gtk_drag_source_set_target_list (GtkWidget *widget,
|
||||
GtkTargetList *target_list)
|
||||
@@ -1448,6 +1548,10 @@ gtk_drag_source_add_text_targets (GtkWidget *widget)
|
||||
gtk_target_list_unref (target_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_drag_source_add_image_targets: (method)
|
||||
* @widget: a #GtkWidget that's is a drag source
|
||||
*/
|
||||
void
|
||||
gtk_drag_source_add_image_targets (GtkWidget *widget)
|
||||
{
|
||||
@@ -1463,6 +1567,10 @@ gtk_drag_source_add_image_targets (GtkWidget *widget)
|
||||
gtk_target_list_unref (target_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_drag_source_add_uri_targets: (method)
|
||||
* @widget: a #GtkWidget that's is a drag source
|
||||
*/
|
||||
void
|
||||
gtk_drag_source_add_uri_targets (GtkWidget *widget)
|
||||
{
|
||||
@@ -1513,6 +1621,11 @@ gtk_drag_source_site_destroy (gpointer data)
|
||||
g_free (site);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_drag_source_set_icon_pixbuf: (method)
|
||||
* @widget: a #GtkWidget
|
||||
* @pixbuf: the #GdkPixbuf for the drag icon
|
||||
*/
|
||||
void
|
||||
gtk_drag_source_set_icon_pixbuf (GtkWidget *widget,
|
||||
GdkPixbuf *pixbuf)
|
||||
@@ -1925,7 +2038,14 @@ _gtk_drag_source_handle_event (GtkWidget *widget,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gtk_drag_check_threshold: (method)
|
||||
* @widget: a #GtkWidget
|
||||
* @start_x: X coordinate of start of drag
|
||||
* @start_y: Y coordinate of start of drag
|
||||
* @current_x: current X coordinate
|
||||
* @current_y: current Y coordinate
|
||||
*/
|
||||
gboolean
|
||||
gtk_drag_check_threshold (GtkWidget *widget,
|
||||
gint start_x,
|
||||
|
||||
@@ -411,6 +411,18 @@ root_key_filter (GdkXEvent *xevent,
|
||||
if ((ev->type == KeyPress || ev->type == KeyRelease) &&
|
||||
ev->xkey.root == ev->xkey.window)
|
||||
ev->xkey.window = (Window)data;
|
||||
else if (ev->type == GenericEvent)
|
||||
{
|
||||
XGenericEventCookie *cookie;
|
||||
XIDeviceEvent *dev;
|
||||
|
||||
cookie = &ev->xcookie;
|
||||
dev = (XIDeviceEvent *) cookie->data;
|
||||
|
||||
if (dev->evtype == XI_KeyPress ||
|
||||
dev->evtype == XI_KeyRelease)
|
||||
dev->event = (Window)data;
|
||||
}
|
||||
|
||||
return GDK_FILTER_CONTINUE;
|
||||
}
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
#include "gtkicontheme.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gtkstylecontextprivate.h"
|
||||
#include "gtktexthandleprivate.h"
|
||||
|
||||
#include "a11y/gtkentryaccessible.h"
|
||||
|
||||
@@ -160,6 +161,8 @@ struct _GtkEntryPrivate
|
||||
|
||||
gchar *placeholder_text;
|
||||
|
||||
GtkTextHandle *text_handle;
|
||||
|
||||
gfloat xalign;
|
||||
|
||||
gint ascent; /* font ascent in pango units */
|
||||
@@ -215,6 +218,7 @@ struct _GtkEntryPrivate
|
||||
guint select_words : 1;
|
||||
guint select_lines : 1;
|
||||
guint truncate_multiline : 1;
|
||||
guint update_handles_on_focus : 1;
|
||||
};
|
||||
|
||||
struct _EntryIconInfo
|
||||
@@ -308,10 +312,13 @@ enum {
|
||||
PROP_IM_MODULE,
|
||||
PROP_EDITING_CANCELED,
|
||||
PROP_PLACEHOLDER_TEXT,
|
||||
PROP_COMPLETION
|
||||
PROP_COMPLETION,
|
||||
PROP_INPUT_PURPOSE,
|
||||
PROP_INPUT_HINTS
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
static gboolean test_touchscreen = FALSE;
|
||||
|
||||
typedef enum {
|
||||
CURSOR_STANDARD,
|
||||
@@ -574,6 +581,13 @@ static GdkPixbuf * gtk_entry_ensure_pixbuf (GtkEntry *en
|
||||
static void gtk_entry_update_cached_style_values(GtkEntry *entry);
|
||||
static gboolean get_middle_click_paste (GtkEntry *entry);
|
||||
|
||||
/* GtkTextHandle handlers */
|
||||
static void gtk_entry_handle_dragged (GtkTextHandle *handle,
|
||||
GtkTextHandlePosition pos,
|
||||
gint x,
|
||||
gint y,
|
||||
GtkEntry *entry);
|
||||
|
||||
/* Completion */
|
||||
static gint gtk_entry_completion_timeout (gpointer data);
|
||||
static gboolean gtk_entry_completion_key_press (GtkWidget *widget,
|
||||
@@ -1359,6 +1373,47 @@ gtk_entry_class_init (GtkEntryClass *class)
|
||||
GTK_TYPE_ENTRY_COMPLETION,
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
/**
|
||||
* GtkEntry:input-purpose:
|
||||
*
|
||||
* The purpose of this text field.
|
||||
*
|
||||
* This property can be used by on-screen keyboards and other input
|
||||
* methods to adjust their behaviour.
|
||||
*
|
||||
* Note that setting the purpose to %GTK_INPUT_PURPOSE_PASSWORD or
|
||||
* %GTK_INPUT_PURPOSE_PIN is independent from setting
|
||||
* #GtkEntry:visibility.
|
||||
*
|
||||
* Since: 3.6
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_INPUT_PURPOSE,
|
||||
g_param_spec_enum ("input-purpose",
|
||||
P_("Purpose"),
|
||||
P_("Purpose of the text field"),
|
||||
GTK_TYPE_INPUT_PURPOSE,
|
||||
GTK_INPUT_PURPOSE_FREE_FORM,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* GtkEntry:input-hints:
|
||||
*
|
||||
* Additional hints (beyond #GtkEntry:input-purpose) that
|
||||
* allow input methods to fine-tune their behaviour.
|
||||
*
|
||||
* Since: 3.6
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_INPUT_HINTS,
|
||||
g_param_spec_flags ("input-hints",
|
||||
P_("hints"),
|
||||
P_("Hints for the text field behaviour"),
|
||||
GTK_TYPE_INPUT_HINTS,
|
||||
GTK_INPUT_HINT_NONE,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
|
||||
/**
|
||||
* GtkEntry:icon-prelight:
|
||||
*
|
||||
@@ -1892,6 +1947,7 @@ gtk_entry_class_init (GtkEntryClass *class)
|
||||
G_PARAM_DEPRECATED));
|
||||
|
||||
g_type_class_add_private (gobject_class, sizeof (GtkEntryPrivate));
|
||||
test_touchscreen = g_getenv ("GTK_TEST_TOUCHSCREEN_FEATURES") != NULL;
|
||||
|
||||
gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_ENTRY_ACCESSIBLE);
|
||||
}
|
||||
@@ -2162,6 +2218,14 @@ gtk_entry_set_property (GObject *object,
|
||||
gtk_entry_set_completion (entry, GTK_ENTRY_COMPLETION (g_value_get_object (value)));
|
||||
break;
|
||||
|
||||
case PROP_INPUT_PURPOSE:
|
||||
gtk_entry_set_input_purpose (entry, g_value_get_enum (value));
|
||||
break;
|
||||
|
||||
case PROP_INPUT_HINTS:
|
||||
gtk_entry_set_input_hints (entry, g_value_get_flags (value));
|
||||
break;
|
||||
|
||||
case PROP_SCROLL_OFFSET:
|
||||
case PROP_CURSOR_POSITION:
|
||||
default:
|
||||
@@ -2386,6 +2450,14 @@ gtk_entry_get_property (GObject *object,
|
||||
g_value_set_object (value, G_OBJECT (gtk_entry_get_completion (entry)));
|
||||
break;
|
||||
|
||||
case PROP_INPUT_PURPOSE:
|
||||
g_value_set_enum (value, gtk_entry_get_input_purpose (entry));
|
||||
break;
|
||||
|
||||
case PROP_INPUT_HINTS:
|
||||
g_value_set_flags (value, gtk_entry_get_input_hints (entry));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -2493,6 +2565,10 @@ gtk_entry_init (GtkEntry *entry)
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_ENTRY);
|
||||
|
||||
gtk_entry_update_cached_style_values (entry);
|
||||
|
||||
priv->text_handle = _gtk_text_handle_new (GTK_WIDGET (entry));
|
||||
g_signal_connect (priv->text_handle, "handle-dragged",
|
||||
G_CALLBACK (gtk_entry_handle_dragged), entry);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2730,6 +2806,7 @@ gtk_entry_finalize (GObject *object)
|
||||
if (priv->recompute_idle)
|
||||
g_source_remove (priv->recompute_idle);
|
||||
|
||||
g_object_unref (priv->text_handle);
|
||||
g_free (priv->placeholder_text);
|
||||
g_free (priv->im_module);
|
||||
|
||||
@@ -2750,10 +2827,10 @@ gtk_entry_get_display_mode (GtkEntry *entry)
|
||||
return DISPLAY_INVISIBLE;
|
||||
}
|
||||
|
||||
static gchar*
|
||||
gtk_entry_get_display_text (GtkEntry *entry,
|
||||
gint start_pos,
|
||||
gint end_pos)
|
||||
gchar*
|
||||
_gtk_entry_get_display_text (GtkEntry *entry,
|
||||
gint start_pos,
|
||||
gint end_pos)
|
||||
{
|
||||
GtkEntryPasswordHint *password_hint;
|
||||
GtkEntryPrivate *priv;
|
||||
@@ -2951,6 +3028,9 @@ gtk_entry_unmap (GtkWidget *widget)
|
||||
EntryIconInfo *icon_info = NULL;
|
||||
gint i;
|
||||
|
||||
_gtk_text_handle_set_mode (priv->text_handle,
|
||||
GTK_TEXT_HANDLE_MODE_NONE);
|
||||
|
||||
for (i = 0; i < MAX_ICONS; i++)
|
||||
{
|
||||
if ((icon_info = priv->icons[i]) != NULL)
|
||||
@@ -3024,7 +3104,7 @@ gtk_entry_realize (GtkWidget *widget)
|
||||
|
||||
gtk_entry_adjust_scroll (entry);
|
||||
gtk_entry_update_primary_selection (entry);
|
||||
|
||||
_gtk_text_handle_set_relative_to (priv->text_handle, priv->text_area);
|
||||
|
||||
/* If the icon positions are already setup, create their windows.
|
||||
* Otherwise if they don't exist yet, then construct_icon_info()
|
||||
@@ -3052,6 +3132,7 @@ gtk_entry_unrealize (GtkWidget *widget)
|
||||
gtk_entry_reset_layout (entry);
|
||||
|
||||
gtk_im_context_set_client_window (priv->im_context, NULL);
|
||||
_gtk_text_handle_set_relative_to (priv->text_handle, NULL);
|
||||
|
||||
clipboard = gtk_widget_get_clipboard (widget, GDK_SELECTION_PRIMARY);
|
||||
if (gtk_clipboard_get_owner (clipboard) == G_OBJECT (entry))
|
||||
@@ -3793,7 +3874,108 @@ in_selection (GtkEntry *entry,
|
||||
g_free (ranges);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_gtk_entry_move_handle (GtkEntry *entry,
|
||||
GtkTextHandlePosition pos,
|
||||
gint x,
|
||||
gint y,
|
||||
gint height)
|
||||
{
|
||||
GtkEntryPrivate *priv = entry->priv;
|
||||
|
||||
if (!_gtk_text_handle_get_is_dragged (priv->text_handle, pos) &&
|
||||
(x < 0 || x > gdk_window_get_width (priv->text_area)))
|
||||
{
|
||||
/* Hide the handle if it's not being manipulated
|
||||
* and fell outside of the visible text area.
|
||||
*/
|
||||
_gtk_text_handle_set_visible (priv->text_handle, pos, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
GdkRectangle rect;
|
||||
|
||||
rect.x = CLAMP (x, 0, gdk_window_get_width (priv->text_area));
|
||||
rect.y = y;
|
||||
rect.width = 1;
|
||||
rect.height = height;
|
||||
|
||||
_gtk_text_handle_set_visible (priv->text_handle, pos, TRUE);
|
||||
_gtk_text_handle_set_position (priv->text_handle, pos, &rect);
|
||||
}
|
||||
}
|
||||
|
||||
static gint
|
||||
_gtk_entry_get_selection_bound_location (GtkEntry *entry)
|
||||
{
|
||||
GtkEntryPrivate *priv = entry->priv;
|
||||
PangoLayout *layout;
|
||||
PangoRectangle pos;
|
||||
gint x;
|
||||
const gchar *text;
|
||||
gint index;
|
||||
|
||||
layout = gtk_entry_ensure_layout (entry, FALSE);
|
||||
text = pango_layout_get_text (layout);
|
||||
index = g_utf8_offset_to_pointer (text, priv->selection_bound) - text;
|
||||
pango_layout_index_to_pos (layout, index, &pos);
|
||||
|
||||
if (gtk_widget_get_direction (GTK_WIDGET (entry)) == GTK_TEXT_DIR_RTL)
|
||||
x = (pos.x + pos.width) / PANGO_SCALE;
|
||||
else
|
||||
x = pos.x / PANGO_SCALE;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_entry_update_handles (GtkEntry *entry,
|
||||
GtkTextHandleMode mode)
|
||||
{
|
||||
GtkEntryPrivate *priv = entry->priv;
|
||||
gint strong_x, height;
|
||||
gint cursor, bound;
|
||||
|
||||
_gtk_text_handle_set_mode (priv->text_handle, mode);
|
||||
|
||||
/* Wait for recomputation before repositioning */
|
||||
if (priv->recompute_idle != 0)
|
||||
return;
|
||||
|
||||
height = gdk_window_get_height (priv->text_area);
|
||||
|
||||
gtk_entry_get_cursor_locations (entry, CURSOR_STANDARD, &strong_x, NULL);
|
||||
cursor = strong_x - priv->scroll_offset;
|
||||
|
||||
if (mode == GTK_TEXT_HANDLE_MODE_SELECTION)
|
||||
{
|
||||
gint start, end;
|
||||
|
||||
bound = _gtk_entry_get_selection_bound_location (entry) - priv->scroll_offset;
|
||||
|
||||
if (priv->selection_bound > priv->current_pos)
|
||||
{
|
||||
start = cursor;
|
||||
end = bound;
|
||||
}
|
||||
else
|
||||
{
|
||||
start = bound;
|
||||
end = cursor;
|
||||
}
|
||||
|
||||
/* Update start selection bound */
|
||||
_gtk_entry_move_handle (entry, GTK_TEXT_HANDLE_POSITION_SELECTION_START,
|
||||
start, 0, height);
|
||||
_gtk_entry_move_handle (entry, GTK_TEXT_HANDLE_POSITION_SELECTION_END,
|
||||
end, 0, height);
|
||||
}
|
||||
else
|
||||
_gtk_entry_move_handle (entry, GTK_TEXT_HANDLE_POSITION_CURSOR,
|
||||
cursor, 0, height);
|
||||
}
|
||||
|
||||
static gint
|
||||
gtk_entry_button_press (GtkWidget *widget,
|
||||
GdkEventButton *event)
|
||||
@@ -3861,7 +4043,14 @@ gtk_entry_button_press (GtkWidget *widget,
|
||||
else if (event->button == GDK_BUTTON_PRIMARY)
|
||||
{
|
||||
gboolean have_selection = gtk_editable_get_selection_bounds (editable, &sel_start, &sel_end);
|
||||
gboolean is_touchscreen;
|
||||
GdkDevice *source;
|
||||
|
||||
source = gdk_event_get_source_device ((GdkEvent *) event);
|
||||
is_touchscreen = test_touchscreen ||
|
||||
gdk_device_get_source (source) == GDK_SOURCE_TOUCHSCREEN;
|
||||
|
||||
priv->update_handles_on_focus = is_touchscreen;
|
||||
priv->select_words = FALSE;
|
||||
priv->select_lines = FALSE;
|
||||
|
||||
@@ -3939,7 +4128,12 @@ gtk_entry_button_press (GtkWidget *widget,
|
||||
priv->drag_start_y = event->y;
|
||||
}
|
||||
else
|
||||
gtk_editable_set_position (editable, tmp_pos);
|
||||
{
|
||||
gtk_editable_set_position (editable, tmp_pos);
|
||||
|
||||
if (is_touchscreen)
|
||||
_gtk_entry_update_handles (entry, GTK_TEXT_HANDLE_MODE_CURSOR);
|
||||
}
|
||||
break;
|
||||
|
||||
case GDK_2BUTTON_PRESS:
|
||||
@@ -3950,6 +4144,9 @@ gtk_entry_button_press (GtkWidget *widget,
|
||||
priv->in_drag = FALSE;
|
||||
priv->select_words = TRUE;
|
||||
gtk_entry_select_word (entry);
|
||||
|
||||
if (is_touchscreen)
|
||||
_gtk_entry_update_handles (entry, GTK_TEXT_HANDLE_MODE_SELECTION);
|
||||
break;
|
||||
|
||||
case GDK_3BUTTON_PRESS:
|
||||
@@ -3960,6 +4157,8 @@ gtk_entry_button_press (GtkWidget *widget,
|
||||
priv->in_drag = FALSE;
|
||||
priv->select_lines = TRUE;
|
||||
gtk_entry_select_line (entry);
|
||||
if (is_touchscreen)
|
||||
_gtk_entry_update_handles (entry, GTK_TEXT_HANDLE_MODE_SELECTION);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -4029,9 +4228,16 @@ gtk_entry_button_release (GtkWidget *widget,
|
||||
if (priv->in_drag)
|
||||
{
|
||||
gint tmp_pos = gtk_entry_find_position (entry, priv->drag_start_x);
|
||||
GdkDevice *source;
|
||||
|
||||
gtk_editable_set_position (GTK_EDITABLE (entry), tmp_pos);
|
||||
|
||||
source = gdk_event_get_source_device ((GdkEvent *) event);
|
||||
|
||||
if (test_touchscreen ||
|
||||
gdk_device_get_source (source) == GDK_SOURCE_TOUCHSCREEN)
|
||||
_gtk_entry_update_handles (entry, GTK_TEXT_HANDLE_MODE_CURSOR);
|
||||
|
||||
priv->in_drag = 0;
|
||||
}
|
||||
|
||||
@@ -4153,13 +4359,22 @@ gtk_entry_motion_notify (GtkWidget *widget,
|
||||
}
|
||||
else
|
||||
{
|
||||
GdkInputSource input_source;
|
||||
GdkDevice *source;
|
||||
guint length;
|
||||
|
||||
length = gtk_entry_buffer_get_length (get_buffer (entry));
|
||||
|
||||
if (event->y < 0)
|
||||
tmp_pos = 0;
|
||||
else if (event->y >= gdk_window_get_height (priv->text_area))
|
||||
tmp_pos = gtk_entry_buffer_get_length (get_buffer (entry));
|
||||
tmp_pos = length;
|
||||
else
|
||||
tmp_pos = gtk_entry_find_position (entry, event->x + priv->scroll_offset);
|
||||
|
||||
source = gdk_event_get_source_device ((GdkEvent *) event);
|
||||
input_source = gdk_device_get_source (source);
|
||||
|
||||
if (priv->select_words)
|
||||
{
|
||||
gint min, max;
|
||||
@@ -4195,13 +4410,20 @@ gtk_entry_motion_notify (GtkWidget *widget,
|
||||
if (priv->current_pos != max)
|
||||
pos = min;
|
||||
}
|
||||
|
||||
|
||||
gtk_entry_set_positions (entry, pos, bound);
|
||||
}
|
||||
else
|
||||
gtk_entry_set_positions (entry, tmp_pos, -1);
|
||||
|
||||
/* Update touch handles' position */
|
||||
if (test_touchscreen || input_source == GDK_SOURCE_TOUCHSCREEN)
|
||||
_gtk_entry_update_handles (entry,
|
||||
(priv->current_pos == priv->selection_bound) ?
|
||||
GTK_TEXT_HANDLE_MODE_CURSOR :
|
||||
GTK_TEXT_HANDLE_MODE_SELECTION);
|
||||
}
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -4241,6 +4463,8 @@ gtk_entry_key_press (GtkWidget *widget,
|
||||
|
||||
gtk_entry_reset_blink_time (entry);
|
||||
gtk_entry_pend_cursor_blink (entry);
|
||||
_gtk_text_handle_set_mode (priv->text_handle,
|
||||
GTK_TEXT_HANDLE_MODE_NONE);
|
||||
|
||||
if (priv->editable)
|
||||
{
|
||||
@@ -4333,6 +4557,10 @@ gtk_entry_focus_in (GtkWidget *widget,
|
||||
gtk_entry_check_cursor_blink (entry);
|
||||
}
|
||||
|
||||
if (priv->update_handles_on_focus &&
|
||||
gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), NULL, NULL))
|
||||
_gtk_entry_update_handles (entry, GTK_TEXT_HANDLE_MODE_SELECTION);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -4345,6 +4573,9 @@ gtk_entry_focus_out (GtkWidget *widget,
|
||||
GtkEntryCompletion *completion;
|
||||
GdkKeymap *keymap;
|
||||
|
||||
_gtk_text_handle_set_mode (priv->text_handle,
|
||||
GTK_TEXT_HANDLE_MODE_NONE);
|
||||
|
||||
gtk_widget_queue_draw (widget);
|
||||
|
||||
keymap = gdk_keymap_get_for_display (gtk_widget_get_display (widget));
|
||||
@@ -5170,8 +5401,8 @@ gtk_entry_backspace (GtkEntry *entry)
|
||||
gchar *normalized_text;
|
||||
glong len;
|
||||
|
||||
cluster_text = gtk_entry_get_display_text (entry, prev_pos,
|
||||
priv->current_pos);
|
||||
cluster_text = _gtk_entry_get_display_text (entry, prev_pos,
|
||||
priv->current_pos);
|
||||
normalized_text = g_utf8_normalize (cluster_text,
|
||||
strlen (cluster_text),
|
||||
G_NORMALIZE_NFD);
|
||||
@@ -5222,7 +5453,7 @@ gtk_entry_copy_clipboard (GtkEntry *entry)
|
||||
return;
|
||||
}
|
||||
|
||||
str = gtk_entry_get_display_text (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);
|
||||
@@ -5380,7 +5611,7 @@ gtk_entry_retrieve_surrounding_cb (GtkIMContext *context,
|
||||
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);
|
||||
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, priv->current_pos) - text);
|
||||
g_free (text);
|
||||
@@ -5526,10 +5757,17 @@ recompute_idle_func (gpointer data)
|
||||
|
||||
if (gtk_widget_has_screen (GTK_WIDGET (entry)))
|
||||
{
|
||||
GtkTextHandleMode handle_mode;
|
||||
|
||||
gtk_entry_adjust_scroll (entry);
|
||||
gtk_widget_queue_draw (GTK_WIDGET (entry));
|
||||
|
||||
update_im_cursor_location (entry);
|
||||
|
||||
handle_mode = _gtk_text_handle_get_mode (priv->text_handle);
|
||||
|
||||
if (handle_mode != GTK_TEXT_HANDLE_MODE_NONE)
|
||||
_gtk_entry_update_handles (entry, handle_mode);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
@@ -5598,7 +5836,7 @@ gtk_entry_create_layout (GtkEntry *entry,
|
||||
|
||||
pango_layout_set_single_paragraph_mode (layout, TRUE);
|
||||
|
||||
display = placeholder_layout ? g_strdup (priv->placeholder_text) : gtk_entry_get_display_text (entry, 0, -1);
|
||||
display = placeholder_layout ? g_strdup (priv->placeholder_text) : _gtk_entry_get_display_text (entry, 0, -1);
|
||||
n_bytes = strlen (display);
|
||||
|
||||
if (!placeholder_layout && include_preedit)
|
||||
@@ -5961,6 +6199,70 @@ gtk_entry_draw_cursor (GtkEntry *entry,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_handle_dragged (GtkTextHandle *handle,
|
||||
GtkTextHandlePosition pos,
|
||||
gint x,
|
||||
gint y,
|
||||
GtkEntry *entry)
|
||||
{
|
||||
gint cursor_pos, selection_bound_pos, tmp_pos;
|
||||
GtkEntryPrivate *priv = entry->priv;
|
||||
GtkTextHandleMode mode;
|
||||
gint *min, *max;
|
||||
|
||||
cursor_pos = priv->current_pos;
|
||||
selection_bound_pos = priv->selection_bound;
|
||||
mode = _gtk_text_handle_get_mode (handle);
|
||||
tmp_pos = gtk_entry_find_position (entry, x + priv->scroll_offset);
|
||||
|
||||
if (mode == GTK_TEXT_HANDLE_MODE_CURSOR ||
|
||||
cursor_pos >= selection_bound_pos)
|
||||
{
|
||||
max = &cursor_pos;
|
||||
min = &selection_bound_pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
max = &selection_bound_pos;
|
||||
min = &cursor_pos;
|
||||
}
|
||||
|
||||
if (pos == GTK_TEXT_HANDLE_POSITION_SELECTION_END)
|
||||
{
|
||||
if (mode == GTK_TEXT_HANDLE_MODE_SELECTION)
|
||||
{
|
||||
gint min_pos;
|
||||
|
||||
min_pos = MAX (*min + 1, 0);
|
||||
tmp_pos = MAX (tmp_pos, min_pos);
|
||||
}
|
||||
|
||||
*max = tmp_pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mode == GTK_TEXT_HANDLE_MODE_SELECTION)
|
||||
{
|
||||
gint max_pos;
|
||||
|
||||
max_pos = *max - 1;
|
||||
*min = MIN (tmp_pos, max_pos);
|
||||
}
|
||||
}
|
||||
|
||||
if (cursor_pos != priv->current_pos ||
|
||||
selection_bound_pos != priv->selection_bound)
|
||||
{
|
||||
if (mode == GTK_TEXT_HANDLE_MODE_CURSOR)
|
||||
gtk_entry_set_positions (entry, cursor_pos, cursor_pos);
|
||||
else
|
||||
gtk_entry_set_positions (entry, cursor_pos, selection_bound_pos);
|
||||
|
||||
_gtk_entry_update_handles (entry, mode);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_entry_reset_im_context (GtkEntry *entry)
|
||||
{
|
||||
@@ -6123,6 +6425,23 @@ gtk_entry_get_cursor_locations (GtkEntry *entry,
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_gtk_entry_get_is_selection_handle_dragged (GtkEntry *entry)
|
||||
{
|
||||
GtkEntryPrivate *priv = entry->priv;
|
||||
GtkTextHandlePosition pos;
|
||||
|
||||
if (_gtk_text_handle_get_mode (priv->text_handle) != GTK_TEXT_HANDLE_MODE_SELECTION)
|
||||
return FALSE;
|
||||
|
||||
if (priv->current_pos >= priv->selection_bound)
|
||||
pos = GTK_TEXT_HANDLE_POSITION_SELECTION_START;
|
||||
else
|
||||
pos = GTK_TEXT_HANDLE_POSITION_SELECTION_END;
|
||||
|
||||
return _gtk_text_handle_get_is_dragged (priv->text_handle, pos);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_adjust_scroll (GtkEntry *entry)
|
||||
{
|
||||
@@ -6135,6 +6454,7 @@ gtk_entry_adjust_scroll (GtkEntry *entry)
|
||||
PangoLayout *layout;
|
||||
PangoLayoutLine *line;
|
||||
PangoRectangle logical_rect;
|
||||
GtkTextHandleMode handle_mode;
|
||||
|
||||
if (!gtk_widget_get_realized (GTK_WIDGET (entry)))
|
||||
return;
|
||||
@@ -6171,22 +6491,33 @@ gtk_entry_adjust_scroll (GtkEntry *entry)
|
||||
|
||||
priv->scroll_offset = CLAMP (priv->scroll_offset, min_offset, max_offset);
|
||||
|
||||
/* And make sure cursors are on screen. Note that the cursor is
|
||||
* actually drawn one pixel into the INNER_BORDER space on
|
||||
* the right, when the scroll is at the utmost right. This
|
||||
* looks better to to me than confining the cursor inside the
|
||||
* border entirely, though it means that the cursor gets one
|
||||
* pixel closer to the edge of the widget on the right than
|
||||
* on the left. This might need changing if one changed
|
||||
* INNER_BORDER from 2 to 1, as one would do on a
|
||||
* small-screen-real-estate display.
|
||||
*
|
||||
* We always make sure that the strong cursor is on screen, and
|
||||
* put the weak cursor on screen if possible.
|
||||
*/
|
||||
if (_gtk_entry_get_is_selection_handle_dragged (entry))
|
||||
{
|
||||
/* The text handle corresponding to the selection bound is
|
||||
* being dragged, ensure it stays onscreen even if we scroll
|
||||
* cursors away, this is so both handles can cause content
|
||||
* to scroll.
|
||||
*/
|
||||
strong_x = weak_x = _gtk_entry_get_selection_bound_location (entry);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* And make sure cursors are on screen. Note that the cursor is
|
||||
* actually drawn one pixel into the INNER_BORDER space on
|
||||
* the right, when the scroll is at the utmost right. This
|
||||
* looks better to to me than confining the cursor inside the
|
||||
* border entirely, though it means that the cursor gets one
|
||||
* pixel closer to the edge of the widget on the right than
|
||||
* on the left. This might need changing if one changed
|
||||
* INNER_BORDER from 2 to 1, as one would do on a
|
||||
* small-screen-real-estate display.
|
||||
*
|
||||
* We always make sure that the strong cursor is on screen, and
|
||||
* put the weak cursor on screen if possible.
|
||||
*/
|
||||
gtk_entry_get_cursor_locations (entry, CURSOR_STANDARD, &strong_x, &weak_x);
|
||||
}
|
||||
|
||||
gtk_entry_get_cursor_locations (entry, CURSOR_STANDARD, &strong_x, &weak_x);
|
||||
|
||||
strong_xoffset = strong_x - priv->scroll_offset;
|
||||
|
||||
if (strong_xoffset < 0)
|
||||
@@ -6213,6 +6544,11 @@ gtk_entry_adjust_scroll (GtkEntry *entry)
|
||||
}
|
||||
|
||||
g_object_notify (G_OBJECT (entry), "scroll-offset");
|
||||
|
||||
handle_mode = _gtk_text_handle_get_mode (priv->text_handle);
|
||||
|
||||
if (handle_mode != GTK_TEXT_HANDLE_MODE_NONE)
|
||||
_gtk_entry_update_handles (entry, handle_mode);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -6235,7 +6571,7 @@ gtk_entry_move_adjustments (GtkEntry *entry)
|
||||
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
|
||||
/* Cursor position, layout offset, border width, and widget allocation */
|
||||
/* Cursor/char position, layout offset, border width, and widget allocation */
|
||||
gtk_entry_get_cursor_locations (entry, CURSOR_STANDARD, &x, NULL);
|
||||
get_layout_position (entry, &layout_x, NULL);
|
||||
_gtk_entry_get_borders (entry, &borders);
|
||||
@@ -6563,7 +6899,7 @@ primary_get_cb (GtkClipboard *clipboard,
|
||||
|
||||
if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &start, &end))
|
||||
{
|
||||
gchar *str = gtk_entry_get_display_text (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);
|
||||
}
|
||||
@@ -6904,14 +7240,19 @@ gtk_entry_set_text (GtkEntry *entry,
|
||||
* @visible: %TRUE if the contents of the entry are displayed
|
||||
* as plaintext
|
||||
*
|
||||
* Sets whether the contents of the entry are visible or not.
|
||||
* When visibility is set to %FALSE, characters are displayed
|
||||
* as the invisible char, and will also appear that way when
|
||||
* Sets whether the contents of the entry are visible or not.
|
||||
* When visibility is set to %FALSE, characters are displayed
|
||||
* as the invisible char, and will also appear that way when
|
||||
* the text in the entry widget is copied elsewhere.
|
||||
*
|
||||
* By default, GTK+ picks the best invisible character available
|
||||
* in the current font, but it can be changed with
|
||||
* gtk_entry_set_invisible_char().
|
||||
*
|
||||
* Note that you probably want to set #GtkEntry:input-purpose
|
||||
* to %GTK_INPUT_PURPOSE_PASSWORD or %GTK_INPUT_PURPOSE_PIN to
|
||||
* inform input methods about the purpose of this entry,
|
||||
* in addition to setting visibility to %FALSE.
|
||||
*/
|
||||
void
|
||||
gtk_entry_set_visibility (GtkEntry *entry,
|
||||
@@ -9102,7 +9443,7 @@ gtk_entry_drag_data_get (GtkWidget *widget,
|
||||
|
||||
if (gtk_editable_get_selection_bounds (editable, &sel_start, &sel_end))
|
||||
{
|
||||
gchar *str = gtk_entry_get_display_text (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);
|
||||
|
||||
@@ -10295,3 +10636,102 @@ _gtk_entry_set_is_cell_renderer (GtkEntry *entry,
|
||||
{
|
||||
entry->priv->is_cell_renderer = is_cell_renderer;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_entry_set_input_purpose:
|
||||
* @entry: a #GtkEntry
|
||||
* @purpose: the purpose
|
||||
*
|
||||
* Sets the #GtkEntry:input-purpose property which
|
||||
* can be used by on-screen keyboards and other input
|
||||
* methods to adjust their behaviour.
|
||||
*
|
||||
* Since: 3.6
|
||||
*/
|
||||
void
|
||||
gtk_entry_set_input_purpose (GtkEntry *entry,
|
||||
GtkInputPurpose purpose)
|
||||
|
||||
{
|
||||
g_return_if_fail (GTK_IS_ENTRY (entry));
|
||||
|
||||
if (gtk_entry_get_input_purpose (entry) != purpose)
|
||||
{
|
||||
g_object_set (G_OBJECT (entry->priv->im_context),
|
||||
"input-purpose", purpose,
|
||||
NULL);
|
||||
|
||||
g_object_notify (G_OBJECT (entry), "input-purpose");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_entry_get_input_purpose:
|
||||
* @entry: a #GtkEntry
|
||||
*
|
||||
* Gets the value of the #GtkEntry:input-purpose property.
|
||||
*
|
||||
* Since: 3.6
|
||||
*/
|
||||
GtkInputPurpose
|
||||
gtk_entry_get_input_purpose (GtkEntry *entry)
|
||||
{
|
||||
GtkInputPurpose purpose;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_ENTRY (entry), GTK_INPUT_PURPOSE_FREE_FORM);
|
||||
|
||||
g_object_get (G_OBJECT (entry->priv->im_context),
|
||||
"input-purpose", &purpose,
|
||||
NULL);
|
||||
|
||||
return purpose;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_entry_set_input_hints:
|
||||
* @entry: a #GtkEntry
|
||||
* @hints: the hints
|
||||
*
|
||||
* Sets the #GtkEntry:input-hints property, which
|
||||
* allows input methods to fine-tune their behaviour.
|
||||
*
|
||||
* Since: 3.6
|
||||
*/
|
||||
void
|
||||
gtk_entry_set_input_hints (GtkEntry *entry,
|
||||
GtkInputHints hints)
|
||||
|
||||
{
|
||||
g_return_if_fail (GTK_IS_ENTRY (entry));
|
||||
|
||||
if (gtk_entry_get_input_hints (entry) != hints)
|
||||
{
|
||||
g_object_set (G_OBJECT (entry->priv->im_context),
|
||||
"input-hints", hints,
|
||||
NULL);
|
||||
|
||||
g_object_notify (G_OBJECT (entry), "input-hints");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_entry_get_input_hints:
|
||||
* @entry: a #GtkEntry
|
||||
*
|
||||
* Gets the value of the #GtkEntry:input-hints property.
|
||||
*
|
||||
* Since: 3.6
|
||||
*/
|
||||
GtkInputHints
|
||||
gtk_entry_get_input_hints (GtkEntry *entry)
|
||||
{
|
||||
GtkInputHints hints;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_ENTRY (entry), GTK_INPUT_HINT_NONE);
|
||||
|
||||
g_object_get (G_OBJECT (entry->priv->im_context),
|
||||
"input-hints", &hints,
|
||||
NULL);
|
||||
|
||||
return hints;
|
||||
}
|
||||
|
||||
@@ -277,6 +277,18 @@ gboolean gtk_entry_im_context_filter_keypress (GtkEntry *
|
||||
GdkEventKey *event);
|
||||
void gtk_entry_reset_im_context (GtkEntry *entry);
|
||||
|
||||
GDK_AVAILABLE_IN_3_6
|
||||
void gtk_entry_set_input_purpose (GtkEntry *entry,
|
||||
GtkInputPurpose purpose);
|
||||
GDK_AVAILABLE_IN_3_6
|
||||
GtkInputPurpose gtk_entry_get_input_purpose (GtkEntry *entry);
|
||||
|
||||
GDK_AVAILABLE_IN_3_6
|
||||
void gtk_entry_set_input_hints (GtkEntry *entry,
|
||||
GtkInputHints hints);
|
||||
GDK_AVAILABLE_IN_3_6
|
||||
GtkInputHints gtk_entry_get_input_hints (GtkEntry *entry);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -77,8 +77,11 @@ void _gtk_entry_completion_popup (GtkEntryCompletion *completion,
|
||||
GdkDevice *device);
|
||||
void _gtk_entry_completion_popdown (GtkEntryCompletion *completion);
|
||||
|
||||
void _gtk_entry_get_borders (GtkEntry *entry,
|
||||
GtkBorder *borders);
|
||||
gchar* _gtk_entry_get_display_text (GtkEntry *entry,
|
||||
gint start_pos,
|
||||
gint end_pos);
|
||||
void _gtk_entry_get_borders (GtkEntry *entry,
|
||||
GtkBorder *borders);
|
||||
void _gtk_entry_reset_im_context (GtkEntry *entry);
|
||||
GtkIMContext* _gtk_entry_get_im_context (GtkEntry *entry);
|
||||
void _gtk_entry_set_is_cell_renderer (GtkEntry *entry,
|
||||
|
||||
@@ -950,5 +950,89 @@ typedef enum {
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
/**
|
||||
* GtkInputPurpose:
|
||||
* @GTK_INPUT_PURPOSE_FREE_FORM: Allow any character
|
||||
* @GTK_INPUT_PURPOSE_ALPHA: Allow only alphabetic characters
|
||||
* @GTK_INPUT_PURPOSE_DIGITS: Allow only digits
|
||||
* @GTK_INPUT_PURPOSE_NUMBER: Edited field expects numbers
|
||||
* @GTK_INPUT_PURPOSE_PHONE: Edited field expects phone number
|
||||
* @GTK_INPUT_PURPOSE_URL: Edited field expects URL
|
||||
* @GTK_INPUT_PURPOSE_EMAIL: Edited field expects email address
|
||||
* @GTK_INPUT_PURPOSE_NAME: Edited field expects the name of a person
|
||||
* @GTK_INPUT_PURPOSE_PASSWORD: Like @GTK_INPUT_PURPOSE_FREE_FORM, but characters are hidden
|
||||
* @GTK_INPUT_PURPOSE_PIN: Like @GTK_INPUT_PURPOSE_DIGITS, but characters are hidden
|
||||
*
|
||||
* Describes primary purpose of the input widget. This information is
|
||||
* useful for on-screen keyboards and similar input methods to decide
|
||||
* which keys should be presented to the user.
|
||||
*
|
||||
* Note that the purpose is not meant to impose a totally strict rule
|
||||
* about allowed characters, and does not replace input validation.
|
||||
* It is fine for an on-screen keyboard to let the user override the
|
||||
* character set restriction that is expressed by the purpose. The
|
||||
* application is expected to validate the entry contents, even if
|
||||
* it specified a purpose.
|
||||
*
|
||||
* The difference between @GTK_INPUT_PURPOSE_DIGITS and
|
||||
* @GTK_INPUT_PURPOSE_NUMBER is that the former accepts only digits
|
||||
* while the latter also some punctuation (like commas or points, plus,
|
||||
* minus) and 'e' or 'E' as in 3.14E+000.
|
||||
*
|
||||
* This enumeration may be extended in the future; input methods should
|
||||
* interpret unknown values as 'free form'.
|
||||
*
|
||||
* Since: 3.6
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GTK_INPUT_PURPOSE_FREE_FORM,
|
||||
GTK_INPUT_PURPOSE_ALPHA,
|
||||
GTK_INPUT_PURPOSE_DIGITS,
|
||||
GTK_INPUT_PURPOSE_NUMBER,
|
||||
GTK_INPUT_PURPOSE_PHONE,
|
||||
GTK_INPUT_PURPOSE_URL,
|
||||
GTK_INPUT_PURPOSE_EMAIL,
|
||||
GTK_INPUT_PURPOSE_NAME,
|
||||
GTK_INPUT_PURPOSE_PASSWORD,
|
||||
GTK_INPUT_PURPOSE_PIN
|
||||
} GtkInputPurpose;
|
||||
|
||||
/**
|
||||
* GtkInputHints:
|
||||
* @GDK_INPUT_HINT_NONE: No special behaviour suggested
|
||||
* @GTK_INPUT_HINT_SPELLCHECK: Suggest checking for typos
|
||||
* @GTK_INPUT_HINT_NO_SPELLCHECK: Suggest not checking for typos
|
||||
* @GTK_INPUT_HINT_WORD_COMPLETION: Suggest word completion
|
||||
* @GTK_INPUT_HINT_LOWERCASE: Suggest to convert all text to lowercase
|
||||
* @GTK_INPUT_HINT_UPPERCASE_CHARS: Suggest to capitalize all text
|
||||
* @GTK_INPUT_HINT_UPPERCASE_WORDS: Suggest to capitalize the first
|
||||
* character of each word
|
||||
* @GTK_INPUT_HINT_UPPERCASE_SENTENCES: Suggest to capitalize the
|
||||
* first word of each sentence
|
||||
*
|
||||
* Describes hints that might be taken into account by input methods
|
||||
* or applications. Note that input methods may already tailor their
|
||||
* behaviour according to the #GtkInputPurpose of the entry.
|
||||
*
|
||||
* Some common sense is expected when using these flags - mixing
|
||||
* @GTK_INPUT_HINT_LOWERCASE with any of the uppercase hints makes no sense.
|
||||
*
|
||||
* This enumeration may be extended in the future; input methods should
|
||||
* ignore unknown values.
|
||||
*
|
||||
* Since: 3.6
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GTK_INPUT_HINT_NONE = 0,
|
||||
GTK_INPUT_HINT_SPELLCHECK = 1 << 0,
|
||||
GTK_INPUT_HINT_NO_SPELLCHECK = 1 << 1,
|
||||
GTK_INPUT_HINT_WORD_COMPLETION = 1 << 2,
|
||||
GTK_INPUT_HINT_LOWERCASE = 1 << 3,
|
||||
GTK_INPUT_HINT_UPPERCASE_CHARS = 1 << 4,
|
||||
GTK_INPUT_HINT_UPPERCASE_WORDS = 1 << 5,
|
||||
GTK_INPUT_HINT_UPPERCASE_SENTENCES = 1 << 6
|
||||
} GtkInputHints;
|
||||
|
||||
#endif /* __GTK_ENUMS_H__ */
|
||||
|
||||
@@ -2249,7 +2249,7 @@ add_idle_while_impl_is_alive (GtkFileChooserDefault *impl, GCallback callback)
|
||||
static gboolean
|
||||
edited_idle_cb (GtkFileChooserDefault *impl)
|
||||
{
|
||||
GDK_THREADS_ENTER ();
|
||||
gdk_threads_enter ();
|
||||
|
||||
g_source_destroy (impl->edited_idle);
|
||||
impl->edited_idle = NULL;
|
||||
@@ -2287,7 +2287,7 @@ edited_idle_cb (GtkFileChooserDefault *impl)
|
||||
impl->edited_new_text = NULL;
|
||||
}
|
||||
|
||||
GDK_THREADS_LEAVE ();
|
||||
gdk_threads_leave ();
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@@ -6779,14 +6779,14 @@ file_system_model_got_thumbnail (GObject *object, GAsyncResult *res, gpointer da
|
||||
if (queried == NULL)
|
||||
return;
|
||||
|
||||
GDK_THREADS_ENTER ();
|
||||
gdk_threads_enter ();
|
||||
|
||||
/* now we know model is valid */
|
||||
|
||||
/* file was deleted */
|
||||
if (!_gtk_file_system_model_get_iter_for_file (model, &iter, file))
|
||||
{
|
||||
GDK_THREADS_LEAVE ();
|
||||
gdk_threads_leave ();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -6800,7 +6800,7 @@ file_system_model_got_thumbnail (GObject *object, GAsyncResult *res, gpointer da
|
||||
|
||||
g_object_unref (info);
|
||||
|
||||
GDK_THREADS_LEAVE ();
|
||||
gdk_threads_leave ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -9333,7 +9333,7 @@ search_entry_activate_cb (GtkEntry *entry,
|
||||
static gboolean
|
||||
focus_entry_idle_cb (GtkFileChooserDefault *impl)
|
||||
{
|
||||
GDK_THREADS_ENTER ();
|
||||
gdk_threads_enter ();
|
||||
|
||||
g_source_destroy (impl->focus_entry_idle);
|
||||
impl->focus_entry_idle = NULL;
|
||||
@@ -9341,7 +9341,7 @@ focus_entry_idle_cb (GtkFileChooserDefault *impl)
|
||||
if (impl->search_entry)
|
||||
gtk_widget_grab_focus (impl->search_entry);
|
||||
|
||||
GDK_THREADS_LEAVE ();
|
||||
gdk_threads_leave ();
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -4575,7 +4575,8 @@ gtk_icon_view_set_tooltip_cell (GtkIconView *icon_view,
|
||||
* @x: (inout): the x coordinate (relative to widget coordinates)
|
||||
* @y: (inout): the y coordinate (relative to widget coordinates)
|
||||
* @keyboard_tip: whether this is a keyboard tooltip or not
|
||||
* @model: (out) (allow-none): a pointer to receive a #GtkTreeModel or %NULL
|
||||
* @model: (out) (allow-none) (transfer none): a pointer to receive a
|
||||
* #GtkTreeModel or %NULL
|
||||
* @path: (out) (allow-none): a pointer to receive a #GtkTreePath or %NULL
|
||||
* @iter: (out) (allow-none): a pointer to receive a #GtkTreeIter or %NULL
|
||||
*
|
||||
@@ -4900,6 +4901,8 @@ void
|
||||
gtk_icon_view_set_model (GtkIconView *icon_view,
|
||||
GtkTreeModel *model)
|
||||
{
|
||||
gboolean dirty;
|
||||
|
||||
g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
|
||||
g_return_if_fail (model == NULL || GTK_IS_TREE_MODEL (model));
|
||||
|
||||
@@ -4916,6 +4919,8 @@ gtk_icon_view_set_model (GtkIconView *icon_view,
|
||||
if (icon_view->priv->cell_area)
|
||||
gtk_cell_area_stop_editing (icon_view->priv->cell_area, TRUE);
|
||||
|
||||
dirty = gtk_icon_view_unselect_all_internal (icon_view);
|
||||
|
||||
if (model)
|
||||
{
|
||||
GType column_type;
|
||||
@@ -5000,6 +5005,9 @@ gtk_icon_view_set_model (GtkIconView *icon_view,
|
||||
|
||||
g_object_notify (G_OBJECT (icon_view), "model");
|
||||
|
||||
if (dirty)
|
||||
g_signal_emit (icon_view, icon_view_signals[SELECTION_CHANGED], 0);
|
||||
|
||||
gtk_widget_queue_resize (GTK_WIDGET (icon_view));
|
||||
}
|
||||
|
||||
@@ -5371,7 +5379,7 @@ gtk_icon_view_unselect_path (GtkIconView *icon_view,
|
||||
*
|
||||
* To free the return value, use:
|
||||
* |[
|
||||
* g_list_free_full (list, (GDestroyNotify) gtk_tree_patch_free);
|
||||
* g_list_free_full (list, (GDestroyNotify) gtk_tree_path_free);
|
||||
* ]|
|
||||
*
|
||||
* Return value: (element-type GtkTreePath) (transfer full): A #GList containing a #GtkTreePath for each selected row.
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <string.h>
|
||||
#include "gtkimcontext.h"
|
||||
#include "gtkprivate.h"
|
||||
#include "gtktypebuiltins.h"
|
||||
#include "gtkmarshalers.h"
|
||||
#include "gtkintl.h"
|
||||
|
||||
@@ -107,7 +108,20 @@ enum {
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint im_context_signals[LAST_SIGNAL] = { 0 };
|
||||
enum {
|
||||
PROP_INPUT_PURPOSE = 1,
|
||||
PROP_INPUT_HINTS,
|
||||
LAST_PROPERTY
|
||||
};
|
||||
|
||||
static guint im_context_signals[LAST_SIGNAL] = { 0, };
|
||||
static GParamSpec *properties[LAST_PROPERTY] = { NULL, };
|
||||
|
||||
typedef struct _GtkIMContextPrivate GtkIMContextPrivate;
|
||||
struct _GtkIMContextPrivate {
|
||||
GtkInputPurpose purpose;
|
||||
GtkInputHints hints;
|
||||
};
|
||||
|
||||
static void gtk_im_context_real_get_preedit_string (GtkIMContext *context,
|
||||
gchar **str,
|
||||
@@ -123,6 +137,16 @@ static void gtk_im_context_real_set_surrounding (GtkIMContext *context,
|
||||
gint len,
|
||||
gint cursor_index);
|
||||
|
||||
static void gtk_im_context_get_property (GObject *obj,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gtk_im_context_set_property (GObject *obj,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE (GtkIMContext, gtk_im_context, G_TYPE_OBJECT)
|
||||
|
||||
/**
|
||||
@@ -185,6 +209,11 @@ G_DEFINE_ABSTRACT_TYPE (GtkIMContext, gtk_im_context, G_TYPE_OBJECT)
|
||||
static void
|
||||
gtk_im_context_class_init (GtkIMContextClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->get_property = gtk_im_context_get_property;
|
||||
object_class->set_property = gtk_im_context_set_property;
|
||||
|
||||
klass->get_preedit_string = gtk_im_context_real_get_preedit_string;
|
||||
klass->filter_keypress = gtk_im_context_real_filter_keypress;
|
||||
klass->get_surrounding = gtk_im_context_real_get_surrounding;
|
||||
@@ -297,6 +326,25 @@ gtk_im_context_class_init (GtkIMContextClass *klass)
|
||||
G_TYPE_BOOLEAN, 2,
|
||||
G_TYPE_INT,
|
||||
G_TYPE_INT);
|
||||
|
||||
properties[PROP_INPUT_PURPOSE] =
|
||||
g_param_spec_enum ("input-purpose",
|
||||
P_("Purpose"),
|
||||
P_("Purpose of the text field"),
|
||||
GTK_TYPE_INPUT_PURPOSE,
|
||||
GTK_INPUT_PURPOSE_FREE_FORM,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_INPUT_HINTS] =
|
||||
g_param_spec_flags ("input-hints",
|
||||
P_("hints"),
|
||||
P_("Hints for the text field behaviour"),
|
||||
GTK_TYPE_INPUT_HINTS,
|
||||
GTK_INPUT_HINT_NONE,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_type_class_add_private (klass, sizeof (GtkIMContextPrivate));
|
||||
g_object_class_install_properties (object_class, LAST_PROPERTY, properties);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -706,3 +754,47 @@ gtk_im_context_delete_surrounding (GtkIMContext *context,
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_im_context_get_property (GObject *obj,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkIMContextPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (obj, GTK_TYPE_IM_CONTEXT, GtkIMContextPrivate);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_INPUT_PURPOSE:
|
||||
g_value_set_enum (value, priv->purpose);
|
||||
break;
|
||||
case PROP_INPUT_HINTS:
|
||||
g_value_set_flags (value, priv->hints);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_im_context_set_property (GObject *obj,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkIMContextPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (obj, GTK_TYPE_IM_CONTEXT, GtkIMContextPrivate);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_INPUT_PURPOSE:
|
||||
priv->purpose = g_value_get_enum (value);
|
||||
break;
|
||||
case PROP_INPUT_HINTS:
|
||||
priv->hints = g_value_get_flags (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,6 +97,8 @@
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "fallback-c89.c"
|
||||
|
||||
#define DEFAULT_BLOCK_SIZE 3
|
||||
|
||||
/* these don't make sense outside of GtkLevelBar, so we don't add
|
||||
@@ -647,7 +649,7 @@ offset_start_element (GMarkupParseContext *context,
|
||||
|
||||
if (name && value_str)
|
||||
{
|
||||
offset = gtk_level_bar_offset_new (name, strtof (value_str, NULL));
|
||||
offset = gtk_level_bar_offset_new (name, g_ascii_strtod (value_str, NULL));
|
||||
parser_data->offsets = g_list_prepend (parser_data->offsets, offset);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1158,9 +1158,9 @@ gtk_main (void)
|
||||
|
||||
if (g_main_loop_is_running (main_loops->data))
|
||||
{
|
||||
GDK_THREADS_LEAVE ();
|
||||
gdk_threads_leave ();
|
||||
g_main_loop_run (loop);
|
||||
GDK_THREADS_ENTER ();
|
||||
gdk_threads_enter ();
|
||||
gdk_flush ();
|
||||
}
|
||||
|
||||
@@ -1235,9 +1235,9 @@ gtk_events_pending (void)
|
||||
{
|
||||
gboolean result;
|
||||
|
||||
GDK_THREADS_LEAVE ();
|
||||
gdk_threads_leave ();
|
||||
result = g_main_context_pending (NULL);
|
||||
GDK_THREADS_ENTER ();
|
||||
gdk_threads_enter ();
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -1258,9 +1258,9 @@ gtk_events_pending (void)
|
||||
gboolean
|
||||
gtk_main_iteration (void)
|
||||
{
|
||||
GDK_THREADS_LEAVE ();
|
||||
gdk_threads_leave ();
|
||||
g_main_context_iteration (NULL, TRUE);
|
||||
GDK_THREADS_ENTER ();
|
||||
gdk_threads_enter ();
|
||||
|
||||
if (main_loops)
|
||||
return !g_main_loop_is_running (main_loops->data);
|
||||
@@ -1282,9 +1282,9 @@ gtk_main_iteration (void)
|
||||
gboolean
|
||||
gtk_main_iteration_do (gboolean blocking)
|
||||
{
|
||||
GDK_THREADS_LEAVE ();
|
||||
gdk_threads_leave ();
|
||||
g_main_context_iteration (NULL, blocking);
|
||||
GDK_THREADS_ENTER ();
|
||||
gdk_threads_enter ();
|
||||
|
||||
if (main_loops)
|
||||
return !g_main_loop_is_running (main_loops->data);
|
||||
|
||||
@@ -69,6 +69,7 @@ VOID:ENUM,FLOAT
|
||||
VOID:ENUM,FLOAT,BOOLEAN
|
||||
VOID:ENUM,INT
|
||||
VOID:ENUM,INT,BOOLEAN
|
||||
VOID:ENUM,INT,INT
|
||||
VOID:ENUM,BOXED
|
||||
VOID:ENUM,STRING
|
||||
VOID:FLAGS
|
||||
|
||||
@@ -1220,6 +1220,8 @@ gtk_menu_attach_to_widget (GtkMenu *menu,
|
||||
/* Attach the widget to the toplevel window. */
|
||||
gtk_window_set_attached_to (GTK_WINDOW (menu->priv->toplevel), attach_widget);
|
||||
|
||||
_gtk_widget_update_parent_muxer (GTK_WIDGET (menu));
|
||||
|
||||
/* Fallback title for menu comes from attach widget */
|
||||
gtk_menu_update_title (menu);
|
||||
|
||||
@@ -1294,6 +1296,8 @@ gtk_menu_detach (GtkMenu *menu)
|
||||
|
||||
g_slice_free (GtkMenuAttachData, data);
|
||||
|
||||
_gtk_widget_update_parent_muxer (GTK_WIDGET (menu));
|
||||
|
||||
/* Fallback title for menu comes from attach widget */
|
||||
gtk_menu_update_title (menu);
|
||||
|
||||
|
||||
@@ -26,9 +26,118 @@
|
||||
* The #GtkMenuButton widget is used to display a menu when clicked on.
|
||||
* This menu can be provided either as a #GtkMenu, or an abstract #GMenuModel.
|
||||
*
|
||||
* The #GtkMenuButton widget can hold any valid child widget. That is, it can hold
|
||||
* almost any other standard #GtkWidget. The most commonly used child is the
|
||||
* provided #GtkArrow.
|
||||
* The #GtkMenuButton widget can hold any valid child widget. That is, it
|
||||
* can hold almost any other standard #GtkWidget. The most commonly used
|
||||
* child is the provided #GtkArrow.
|
||||
*
|
||||
* The positioning of the menu is determined by the #GtkMenuButton:direction
|
||||
* property of the menu button and the #GtkWidget:halign or #GtkWidget:valign
|
||||
* properties of the menu. For example, when the direction is %GTK_ARROW_DOWN
|
||||
* and the horizontal alignment is %GTK_ALIGN_START, the menu will be
|
||||
* positioned below the button, with the starting edge (depending on the
|
||||
* text direction) of the menu aligned with the starting edge of the button.
|
||||
* If there is not enough space below the button, the menu is popped up above
|
||||
* the button instead. If the alignment would move part of the menu offscreen,
|
||||
* it is 'pushed in'.
|
||||
*
|
||||
* <informaltable>
|
||||
* <tgroup cols="4">
|
||||
* <tbody>
|
||||
* <row>
|
||||
* <entry></entry>
|
||||
* <entry>halign = start</entry>
|
||||
* <entry>halign = center</entry>
|
||||
* <entry>halign = end</entry>
|
||||
* </row>
|
||||
* <row>
|
||||
* <entry>direction = down</entry>
|
||||
* <entry>
|
||||
* <inlinemediaobject>
|
||||
* <imageobject><imagedata fileref="down-start.png" format="PNG"/></imageobject>
|
||||
* </inlinemediaobject>
|
||||
* </entry>
|
||||
* <entry>
|
||||
* <inlinemediaobject>
|
||||
* <imageobject><imagedata fileref="down-center.png" format="PNG"/></imageobject>
|
||||
* </inlinemediaobject>
|
||||
* </entry>
|
||||
* <entry>
|
||||
* <inlinemediaobject>
|
||||
* <imageobject><imagedata fileref="down-end.png" format="PNG"/></imageobject>
|
||||
* </inlinemediaobject>
|
||||
* </entry>
|
||||
* </row>
|
||||
* <row>
|
||||
* <entry>direction = up</entry>
|
||||
* <entry>
|
||||
* <inlinemediaobject>
|
||||
* <imageobject><imagedata fileref="up-start.png" format="PNG"/></imageobject>
|
||||
* </inlinemediaobject>
|
||||
* </entry>
|
||||
* <entry>
|
||||
* <inlinemediaobject>
|
||||
* <imageobject><imagedata fileref="up-center.png" format="PNG"/></imageobject>
|
||||
* </inlinemediaobject>
|
||||
* </entry>
|
||||
* <entry>
|
||||
* <inlinemediaobject>
|
||||
* <imageobject><imagedata fileref="up-end.png" format="PNG"/></imageobject>
|
||||
* </inlinemediaobject>
|
||||
* </entry>
|
||||
* </row>
|
||||
* </tbody>
|
||||
* </tgroup>
|
||||
* </informaltable>
|
||||
* <informaltable>
|
||||
* <tgroup cols="3">
|
||||
* <tbody>
|
||||
* <row>
|
||||
* <entry></entry>
|
||||
* <entry>direction = left</entry>
|
||||
* <entry>direction = right</entry>
|
||||
* </row>
|
||||
* <row>
|
||||
* <entry>valign = start</entry>
|
||||
* <entry>
|
||||
* <inlinemediaobject>
|
||||
* <imageobject><imagedata fileref="left-start.png" format="PNG"/></imageobject>
|
||||
* </inlinemediaobject>
|
||||
* </entry>
|
||||
* <entry>
|
||||
* <inlinemediaobject>
|
||||
* <imageobject><imagedata fileref="right-start.png" format="PNG"/></imageobject>
|
||||
* </inlinemediaobject>
|
||||
* </entry>
|
||||
* </row>
|
||||
* <row>
|
||||
* <entry>valign = center</entry>
|
||||
* <entry>
|
||||
* <inlinemediaobject>
|
||||
* <imageobject><imagedata fileref="left-center.png" format="PNG"/></imageobject>
|
||||
* </inlinemediaobject>
|
||||
* </entry>
|
||||
* <entry>
|
||||
* <inlinemediaobject>
|
||||
* <imageobject><imagedata fileref="right-center.png" format="PNG"/></imageobject>
|
||||
* </inlinemediaobject>
|
||||
* </entry>
|
||||
* </row>
|
||||
* <row>
|
||||
* <entry>valign = end</entry>
|
||||
* <entry>
|
||||
* <inlinemediaobject>
|
||||
* <imageobject><imagedata fileref="left-end.png" format="PNG"/></imageobject>
|
||||
* </inlinemediaobject>
|
||||
* </entry>
|
||||
* <entry>
|
||||
* <inlinemediaobject>
|
||||
* <imageobject><imagedata fileref="right-end.png" format="PNG"/></imageobject>
|
||||
* </inlinemediaobject>
|
||||
* </entry>
|
||||
* </row>
|
||||
* </tbody>
|
||||
* </tgroup>
|
||||
* </informaltable>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@@ -42,7 +151,7 @@
|
||||
|
||||
struct _GtkMenuButtonPrivate
|
||||
{
|
||||
GtkWidget *menu;
|
||||
GtkWidget *popup;
|
||||
GMenuModel *model;
|
||||
|
||||
GtkMenuButtonShowMenuCallback func;
|
||||
@@ -56,7 +165,7 @@ struct _GtkMenuButtonPrivate
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_MENU,
|
||||
PROP_POPUP,
|
||||
PROP_MODEL,
|
||||
PROP_ALIGN_WIDGET,
|
||||
PROP_DIRECTION
|
||||
@@ -64,7 +173,7 @@ enum
|
||||
|
||||
G_DEFINE_TYPE(GtkMenuButton, gtk_menu_button, GTK_TYPE_TOGGLE_BUTTON)
|
||||
|
||||
static void gtk_menu_button_finalize (GObject *object);
|
||||
static void gtk_menu_button_dispose (GObject *object);
|
||||
|
||||
static void
|
||||
gtk_menu_button_set_property (GObject *object,
|
||||
@@ -76,8 +185,8 @@ gtk_menu_button_set_property (GObject *object,
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_MENU:
|
||||
gtk_menu_button_set_menu (self, g_value_get_object (value));
|
||||
case PROP_POPUP:
|
||||
gtk_menu_button_set_popup (self, g_value_get_object (value));
|
||||
break;
|
||||
case PROP_MODEL:
|
||||
gtk_menu_button_set_menu_model (self, g_value_get_object (value));
|
||||
@@ -103,8 +212,8 @@ gtk_menu_button_get_property (GObject *object,
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_MENU:
|
||||
g_value_set_object (value, priv->menu);
|
||||
case PROP_POPUP:
|
||||
g_value_set_object (value, priv->popup);
|
||||
break;
|
||||
case PROP_MODEL:
|
||||
g_value_set_object (value, priv->model);
|
||||
@@ -127,16 +236,16 @@ gtk_menu_button_state_flags_changed (GtkWidget *widget,
|
||||
GtkMenuButton *button = GTK_MENU_BUTTON (widget);
|
||||
GtkMenuButtonPrivate *priv = button->priv;
|
||||
|
||||
if (!gtk_widget_is_sensitive (widget) && priv->menu)
|
||||
gtk_menu_shell_deactivate (GTK_MENU_SHELL (priv->menu));
|
||||
if (!gtk_widget_is_sensitive (widget) && priv->popup)
|
||||
gtk_menu_shell_deactivate (GTK_MENU_SHELL (priv->popup));
|
||||
}
|
||||
|
||||
static void
|
||||
menu_position_down_func (GtkMenu *menu,
|
||||
gint *x,
|
||||
gint *y,
|
||||
gboolean *push_in,
|
||||
GtkMenuButton *menu_button)
|
||||
menu_position_up_down_func (GtkMenu *menu,
|
||||
gint *x,
|
||||
gint *y,
|
||||
gboolean *push_in,
|
||||
GtkMenuButton *menu_button)
|
||||
{
|
||||
GtkMenuButtonPrivate *priv = menu_button->priv;
|
||||
GtkWidget *widget = GTK_WIDGET (menu_button);
|
||||
@@ -147,14 +256,12 @@ menu_position_down_func (GtkMenu *menu,
|
||||
GdkScreen *screen;
|
||||
GdkWindow *window;
|
||||
GtkAllocation allocation, arrow_allocation;
|
||||
GtkWidget *toplevel;
|
||||
GtkAlign align;
|
||||
|
||||
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (priv->menu));
|
||||
gtk_window_set_type_hint (GTK_WINDOW (toplevel), GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU);
|
||||
|
||||
gtk_widget_get_preferred_size (GTK_WIDGET (priv->menu),
|
||||
gtk_widget_get_preferred_size (GTK_WIDGET (priv->popup),
|
||||
&menu_req, NULL);
|
||||
|
||||
align = gtk_widget_get_halign (GTK_WIDGET (priv->popup));
|
||||
direction = gtk_widget_get_direction (widget);
|
||||
window = gtk_widget_get_window (priv->align_widget ? priv->align_widget : widget);
|
||||
|
||||
@@ -171,71 +278,32 @@ menu_position_down_func (GtkMenu *menu,
|
||||
*x += allocation.x;
|
||||
*y += allocation.y;
|
||||
|
||||
if (direction == GTK_TEXT_DIR_LTR)
|
||||
/* treat the default align value like START */
|
||||
if (align == GTK_ALIGN_FILL)
|
||||
align = GTK_ALIGN_START;
|
||||
|
||||
if (align == GTK_ALIGN_CENTER)
|
||||
*x -= (menu_req.width - allocation.width) / 2;
|
||||
else if ((align == GTK_ALIGN_START && direction == GTK_TEXT_DIR_LTR) ||
|
||||
(align == GTK_ALIGN_END && direction == GTK_TEXT_DIR_RTL))
|
||||
*x += MAX (allocation.width - menu_req.width, 0);
|
||||
else if (menu_req.width > allocation.width)
|
||||
*x -= menu_req.width - allocation.width;
|
||||
|
||||
if ((*y + arrow_allocation.height + menu_req.height) <= monitor.y + monitor.height)
|
||||
*y += arrow_allocation.height;
|
||||
else if ((*y - menu_req.height) >= monitor.y)
|
||||
*y -= menu_req.height;
|
||||
else if (monitor.y + monitor.height - (*y + arrow_allocation.height) > *y)
|
||||
*y += arrow_allocation.height;
|
||||
else
|
||||
*y -= menu_req.height;
|
||||
|
||||
*push_in = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
menu_position_up_func (GtkMenu *menu,
|
||||
gint *x,
|
||||
gint *y,
|
||||
gboolean *push_in,
|
||||
GtkMenuButton *menu_button)
|
||||
{
|
||||
GtkMenuButtonPrivate *priv = menu_button->priv;
|
||||
GtkWidget *widget = GTK_WIDGET (menu_button);
|
||||
GtkRequisition menu_req;
|
||||
GtkTextDirection direction;
|
||||
GdkRectangle monitor;
|
||||
gint monitor_num;
|
||||
GdkScreen *screen;
|
||||
GdkWindow *window;
|
||||
GtkAllocation allocation, arrow_allocation;
|
||||
|
||||
gtk_widget_get_preferred_size (GTK_WIDGET (priv->menu),
|
||||
&menu_req, NULL);
|
||||
|
||||
direction = gtk_widget_get_direction (widget);
|
||||
window = gtk_widget_get_window (priv->align_widget ? priv->align_widget : widget);
|
||||
|
||||
screen = gtk_widget_get_screen (GTK_WIDGET (menu));
|
||||
monitor_num = gdk_screen_get_monitor_at_window (screen, window);
|
||||
if (monitor_num < 0)
|
||||
monitor_num = 0;
|
||||
gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
|
||||
|
||||
gtk_widget_get_allocation (priv->align_widget ? priv->align_widget : widget, &allocation);
|
||||
gtk_widget_get_allocation (widget, &arrow_allocation);
|
||||
|
||||
gdk_window_get_origin (window, x, y);
|
||||
*x += allocation.x;
|
||||
*y += allocation.y;
|
||||
|
||||
if (direction == GTK_TEXT_DIR_LTR)
|
||||
*x += MAX (allocation.width - menu_req.width, 0);
|
||||
else if (menu_req.width > allocation.width)
|
||||
*x -= menu_req.width - allocation.width;
|
||||
|
||||
*y -= menu_req.height;
|
||||
|
||||
/* If we're going to clip the top, pop down instead */
|
||||
if (*y < monitor.y)
|
||||
if (priv->arrow_type == GTK_ARROW_UP && *y - menu_req.height >= monitor.y)
|
||||
{
|
||||
menu_position_down_func (menu, x, y, push_in, menu_button);
|
||||
return;
|
||||
*y -= menu_req.height;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((*y + arrow_allocation.height + menu_req.height) <= monitor.y + monitor.height)
|
||||
*y += arrow_allocation.height;
|
||||
else if ((*y - menu_req.height) >= monitor.y)
|
||||
*y -= menu_req.height;
|
||||
else if (monitor.y + monitor.height - (*y + arrow_allocation.height) > *y)
|
||||
*y += arrow_allocation.height;
|
||||
else
|
||||
*y -= menu_req.height;
|
||||
}
|
||||
|
||||
*push_in = FALSE;
|
||||
@@ -249,19 +317,21 @@ menu_position_side_func (GtkMenu *menu,
|
||||
GtkMenuButton *menu_button)
|
||||
{
|
||||
GtkMenuButtonPrivate *priv = menu_button->priv;
|
||||
GtkAllocation toggle_allocation;
|
||||
GtkAllocation allocation;
|
||||
GtkWidget *widget = GTK_WIDGET (menu_button);
|
||||
GtkRequisition menu_req;
|
||||
GdkRectangle monitor;
|
||||
gint monitor_num;
|
||||
GdkScreen *screen;
|
||||
GdkWindow *window;
|
||||
GtkAlign align;
|
||||
|
||||
gtk_widget_get_preferred_size (GTK_WIDGET (priv->menu),
|
||||
gtk_widget_get_preferred_size (GTK_WIDGET (priv->popup),
|
||||
&menu_req, NULL);
|
||||
|
||||
window = gtk_widget_get_window (widget);
|
||||
|
||||
align = gtk_widget_get_valign (GTK_WIDGET (menu));
|
||||
screen = gtk_widget_get_screen (GTK_WIDGET (menu));
|
||||
monitor_num = gdk_screen_get_monitor_at_window (screen, window);
|
||||
if (monitor_num < 0)
|
||||
@@ -270,16 +340,31 @@ menu_position_side_func (GtkMenu *menu,
|
||||
|
||||
gdk_window_get_origin (gtk_button_get_event_window (GTK_BUTTON (menu_button)), x, y);
|
||||
|
||||
gtk_widget_get_allocation (widget, &toggle_allocation);
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
|
||||
if (priv->arrow_type == GTK_ARROW_RIGHT)
|
||||
*x += toggle_allocation.width;
|
||||
{
|
||||
if (*x + allocation.width + menu_req.width <= monitor.x + monitor.width)
|
||||
*x += allocation.width;
|
||||
else
|
||||
*x -= menu_req.width;
|
||||
}
|
||||
else
|
||||
*x -= menu_req.width;
|
||||
{
|
||||
if (*x - menu_req.width >= monitor.x)
|
||||
*x -= menu_req.width;
|
||||
else
|
||||
*x += allocation.width;
|
||||
}
|
||||
|
||||
if (*y + menu_req.height > monitor.y + monitor.height &&
|
||||
*y + toggle_allocation.height - monitor.y > monitor.y + monitor.height - *y)
|
||||
*y += toggle_allocation.height - menu_req.height;
|
||||
/* treat the default align value like START */
|
||||
if (align == GTK_ALIGN_FILL)
|
||||
align = GTK_ALIGN_START;
|
||||
|
||||
if (align == GTK_ALIGN_CENTER)
|
||||
*y -= (menu_req.height - allocation.height) / 2;
|
||||
else if (align == GTK_ALIGN_END)
|
||||
*y -= menu_req.height - allocation.height;
|
||||
|
||||
*push_in = FALSE;
|
||||
}
|
||||
@@ -294,24 +379,21 @@ popup_menu (GtkMenuButton *menu_button,
|
||||
if (priv->func)
|
||||
priv->func (priv->user_data);
|
||||
|
||||
if (!priv->menu)
|
||||
if (!priv->popup)
|
||||
return;
|
||||
|
||||
switch (priv->arrow_type)
|
||||
{
|
||||
case GTK_ARROW_UP:
|
||||
func = (GtkMenuPositionFunc) menu_position_up_func;
|
||||
break;
|
||||
case GTK_ARROW_LEFT:
|
||||
case GTK_ARROW_RIGHT:
|
||||
func = (GtkMenuPositionFunc) menu_position_side_func;
|
||||
break;
|
||||
default:
|
||||
func = (GtkMenuPositionFunc) menu_position_down_func;
|
||||
func = (GtkMenuPositionFunc) menu_position_up_down_func;
|
||||
break;
|
||||
}
|
||||
|
||||
gtk_menu_popup_for_device (GTK_MENU (priv->menu),
|
||||
gtk_menu_popup_for_device (GTK_MENU (priv->popup),
|
||||
event ? event->device : NULL,
|
||||
NULL, NULL,
|
||||
func,
|
||||
@@ -327,17 +409,17 @@ gtk_menu_button_toggled (GtkToggleButton *button)
|
||||
GtkMenuButton *menu_button = GTK_MENU_BUTTON (button);
|
||||
GtkMenuButtonPrivate *priv = menu_button->priv;
|
||||
|
||||
if (!priv->menu)
|
||||
if (!priv->popup)
|
||||
return;
|
||||
|
||||
if (gtk_toggle_button_get_active (button) &&
|
||||
!gtk_widget_get_visible (GTK_WIDGET (priv->menu)))
|
||||
!gtk_widget_get_visible (GTK_WIDGET (priv->popup)))
|
||||
{
|
||||
/* we get here only when the menu is activated by a key
|
||||
* press, so that we can select the first menu item
|
||||
*/
|
||||
popup_menu (menu_button, NULL);
|
||||
gtk_menu_shell_select_first (GTK_MENU_SHELL (priv->menu), FALSE);
|
||||
gtk_menu_shell_select_first (GTK_MENU_SHELL (priv->popup), FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -367,7 +449,7 @@ gtk_menu_button_class_init (GtkMenuButtonClass *klass)
|
||||
|
||||
gobject_class->set_property = gtk_menu_button_set_property;
|
||||
gobject_class->get_property = gtk_menu_button_get_property;
|
||||
gobject_class->finalize = gtk_menu_button_finalize;
|
||||
gobject_class->dispose = gtk_menu_button_dispose;
|
||||
|
||||
widget_class->state_flags_changed = gtk_menu_button_state_flags_changed;
|
||||
widget_class->button_press_event = gtk_menu_button_button_press_event;
|
||||
@@ -375,19 +457,35 @@ gtk_menu_button_class_init (GtkMenuButtonClass *klass)
|
||||
toggle_button_class->toggled = gtk_menu_button_toggled;
|
||||
|
||||
/**
|
||||
* GtkMenuButton:menu:
|
||||
* GtkMenuButton:popup:
|
||||
*
|
||||
* The #GtkMenu that will be popped up when the button is clicked.
|
||||
*
|
||||
* Since: 3.6
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_MENU,
|
||||
PROP_POPUP,
|
||||
g_param_spec_object ("popup",
|
||||
P_("popup"),
|
||||
P_("The dropdown menu."),
|
||||
GTK_TYPE_MENU,
|
||||
G_PARAM_READWRITE));
|
||||
/**
|
||||
* GtkMenuButton:menu:
|
||||
*
|
||||
* The #GtkMenu that will be popped up when the button is clicked.
|
||||
* This property has been renamed to "popup". "menu" will be
|
||||
* removed before 3.6.0.
|
||||
*
|
||||
* Since: 3.6
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_POPUP, /* [sic] */
|
||||
g_param_spec_object ("menu",
|
||||
P_("menu"),
|
||||
P_("The dropdown menu."),
|
||||
GTK_TYPE_MENU,
|
||||
G_PARAM_READWRITE));
|
||||
G_PARAM_DEPRECATED | G_PARAM_READWRITE));
|
||||
/**
|
||||
* GtkMenuButton:menu-model:
|
||||
*
|
||||
@@ -497,9 +595,9 @@ menu_detacher (GtkWidget *widget,
|
||||
{
|
||||
GtkMenuButtonPrivate *priv = GTK_MENU_BUTTON (widget)->priv;
|
||||
|
||||
g_return_if_fail (priv->menu == (GtkWidget *) menu);
|
||||
g_return_if_fail (priv->popup == (GtkWidget *) menu);
|
||||
|
||||
priv->menu = NULL;
|
||||
priv->popup = NULL;
|
||||
}
|
||||
|
||||
/* This function is used in GtkMenuToolButton, the call back will
|
||||
@@ -507,10 +605,10 @@ menu_detacher (GtkWidget *widget,
|
||||
* signal.
|
||||
*/
|
||||
void
|
||||
_gtk_menu_button_set_menu_with_func (GtkMenuButton *menu_button,
|
||||
GtkWidget *menu,
|
||||
GtkMenuButtonShowMenuCallback func,
|
||||
gpointer user_data)
|
||||
_gtk_menu_button_set_popup_with_func (GtkMenuButton *menu_button,
|
||||
GtkWidget *menu,
|
||||
GtkMenuButtonShowMenuCallback func,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkMenuButtonPrivate *priv;
|
||||
|
||||
@@ -521,33 +619,33 @@ _gtk_menu_button_set_menu_with_func (GtkMenuButton *menu_button,
|
||||
priv->func = func;
|
||||
priv->user_data = user_data;
|
||||
|
||||
if (priv->menu == GTK_WIDGET (menu))
|
||||
if (priv->popup == GTK_WIDGET (menu))
|
||||
return;
|
||||
|
||||
if (priv->menu)
|
||||
if (priv->popup)
|
||||
{
|
||||
if (gtk_widget_get_visible (GTK_WIDGET (priv->menu)))
|
||||
gtk_menu_shell_deactivate (GTK_MENU_SHELL (priv->menu));
|
||||
if (gtk_widget_get_visible (GTK_WIDGET (priv->popup)))
|
||||
gtk_menu_shell_deactivate (GTK_MENU_SHELL (priv->popup));
|
||||
}
|
||||
|
||||
if (priv->menu)
|
||||
if (priv->popup)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (priv->menu,
|
||||
g_signal_handlers_disconnect_by_func (priv->popup,
|
||||
menu_deactivate_cb,
|
||||
menu_button);
|
||||
gtk_menu_detach (GTK_MENU (priv->menu));
|
||||
gtk_menu_detach (GTK_MENU (priv->popup));
|
||||
}
|
||||
|
||||
priv->menu = menu;
|
||||
priv->popup = menu;
|
||||
|
||||
if (priv->menu)
|
||||
if (priv->popup)
|
||||
{
|
||||
gtk_menu_attach_to_widget (GTK_MENU (priv->menu), GTK_WIDGET (menu_button),
|
||||
gtk_menu_attach_to_widget (GTK_MENU (priv->popup), GTK_WIDGET (menu_button),
|
||||
menu_detacher);
|
||||
|
||||
gtk_widget_set_sensitive (GTK_WIDGET (menu_button), TRUE);
|
||||
|
||||
g_signal_connect (priv->menu, "deactivate",
|
||||
g_signal_connect (priv->popup, "deactivate",
|
||||
G_CALLBACK (menu_deactivate_cb), menu_button);
|
||||
}
|
||||
else
|
||||
@@ -560,9 +658,9 @@ _gtk_menu_button_set_menu_with_func (GtkMenuButton *menu_button,
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_menu_button_set_menu:
|
||||
* gtk_menu_button_set_popup:
|
||||
* @menu_button: a #GtkMenuButton
|
||||
* @menu: (allow-none): a #GtkMenu
|
||||
* @popup: (allow-none): a #GtkMenu
|
||||
*
|
||||
* Sets the #GtkMenu that will be popped up when the button is clicked,
|
||||
* or %NULL to disable the button. If #GtkMenuButton:menu-model is set,
|
||||
@@ -571,22 +669,22 @@ _gtk_menu_button_set_menu_with_func (GtkMenuButton *menu_button,
|
||||
* Since: 3.6
|
||||
*/
|
||||
void
|
||||
gtk_menu_button_set_menu (GtkMenuButton *menu_button,
|
||||
GtkWidget *menu)
|
||||
gtk_menu_button_set_popup (GtkMenuButton *menu_button,
|
||||
GtkWidget *popup)
|
||||
{
|
||||
GtkMenuButtonPrivate *priv;
|
||||
|
||||
g_return_if_fail (GTK_IS_MENU_BUTTON (menu_button));
|
||||
g_return_if_fail (GTK_IS_MENU (menu) || menu == NULL);
|
||||
g_return_if_fail (GTK_IS_MENU (popup) || popup == NULL);
|
||||
|
||||
priv = menu_button->priv;
|
||||
g_clear_object (&priv->model);
|
||||
|
||||
_gtk_menu_button_set_menu_with_func (menu_button, menu, NULL, NULL);
|
||||
_gtk_menu_button_set_popup_with_func (menu_button, popup, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_menu_button_get_menu:
|
||||
* gtk_menu_button_get_popup:
|
||||
* @menu_button: a #GtkMenuButton
|
||||
*
|
||||
* Returns the #GtkMenu that pops out of the button.
|
||||
@@ -596,11 +694,24 @@ gtk_menu_button_set_menu (GtkMenuButton *menu_button,
|
||||
* Since: 3.6
|
||||
*/
|
||||
GtkMenu *
|
||||
gtk_menu_button_get_menu (GtkMenuButton *menu_button)
|
||||
gtk_menu_button_get_popup (GtkMenuButton *menu_button)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_MENU_BUTTON (menu_button), NULL);
|
||||
|
||||
return GTK_MENU (menu_button->priv->menu);
|
||||
return GTK_MENU (menu_button->priv->popup);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_menu_button_set_menu (GtkMenuButton *menu_button,
|
||||
GtkWidget *menu)
|
||||
{
|
||||
gtk_menu_button_set_popup (menu_button, menu);
|
||||
}
|
||||
|
||||
GtkMenu *
|
||||
gtk_menu_button_get_menu (GtkMenuButton *menu_button)
|
||||
{
|
||||
return gtk_menu_button_get_popup (menu_button);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -634,14 +745,14 @@ gtk_menu_button_set_menu_model (GtkMenuButton *menu_button,
|
||||
|
||||
if (menu_model == NULL)
|
||||
{
|
||||
gtk_menu_button_set_menu (menu_button, NULL);
|
||||
gtk_menu_button_set_popup (menu_button, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
priv->model = g_object_ref (menu_model);
|
||||
menu = gtk_menu_new_from_model (menu_model);
|
||||
gtk_widget_show_all (menu);
|
||||
gtk_menu_button_set_menu (menu_button, menu);
|
||||
gtk_menu_button_set_popup (menu_button, menu);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -772,19 +883,19 @@ gtk_menu_button_get_direction (GtkMenuButton *menu_button)
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_menu_button_finalize (GObject *object)
|
||||
gtk_menu_button_dispose (GObject *object)
|
||||
{
|
||||
GtkMenuButtonPrivate *priv = GTK_MENU_BUTTON (object)->priv;
|
||||
|
||||
if (priv->menu)
|
||||
if (priv->popup)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (priv->menu,
|
||||
g_signal_handlers_disconnect_by_func (priv->popup,
|
||||
menu_deactivate_cb,
|
||||
object);
|
||||
gtk_menu_detach (GTK_MENU (priv->menu));
|
||||
gtk_menu_detach (GTK_MENU (priv->popup));
|
||||
}
|
||||
|
||||
g_clear_object (&priv->model);
|
||||
|
||||
G_OBJECT_CLASS (gtk_menu_button_parent_class)->finalize (object);
|
||||
G_OBJECT_CLASS (gtk_menu_button_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
@@ -65,9 +65,15 @@ GDK_AVAILABLE_IN_3_6
|
||||
GtkWidget *gtk_menu_button_new (void);
|
||||
|
||||
GDK_AVAILABLE_IN_3_6
|
||||
void gtk_menu_button_set_popup (GtkMenuButton *menu_button,
|
||||
GtkWidget *popup);
|
||||
GDK_AVAILABLE_IN_3_6
|
||||
GtkMenu *gtk_menu_button_get_popup (GtkMenuButton *menu_button);
|
||||
|
||||
GDK_DEPRECATED_IN_3_6_FOR(gtk_menu_button_set_popup)
|
||||
void gtk_menu_button_set_menu (GtkMenuButton *menu_button,
|
||||
GtkWidget *menu);
|
||||
GDK_AVAILABLE_IN_3_6
|
||||
GDK_DEPRECATED_IN_3_6_FOR(gtk_menu_button_get_popup)
|
||||
GtkMenu *gtk_menu_button_get_menu (GtkMenuButton *menu_button);
|
||||
|
||||
GDK_AVAILABLE_IN_3_6
|
||||
|
||||