From 80c73b508c9ac5f3fb2d8cafafffebbf466ea042 Mon Sep 17 00:00:00 2001 From: Albrecht Schlosser Date: Sun, 23 Mar 2025 15:04:40 +0100 Subject: Fluid documentation: fix image name "main_window.png" Remove prefix "Fluid." from generated image name. --- fluid/tools/autodoc.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fluid/tools/autodoc.cxx b/fluid/tools/autodoc.cxx index c87b59bc2..d7d8b14e4 100644 --- a/fluid/tools/autodoc.cxx +++ b/fluid/tools/autodoc.cxx @@ -418,7 +418,7 @@ void run_autodoc(const std::string &target_dir) { // explain widget browser // explain widget browser entry Fluid.main_window->size(350, 320); - fl_snapshot((target_dir + "Fluid.main_window.png").c_str(), Fluid.main_window, win_margin, win_blend); + fl_snapshot((target_dir + "main_window.png").c_str(), Fluid.main_window, win_margin, win_blend); fl_snapshot((target_dir + "main_menubar.png").c_str(), Fluid.main_menubar, row_margin, row_blend); fl_snapshot((target_dir + "main_browser.png").c_str(), widget_browser, FL_SNAP_AREA_CLEAR, Fl_Rect(0, 30, FL_SNAP_TO_WINDOW, 100), row_blend, 2.0); -- cgit v1.2.3 From de3b521f1185220096c3afea65aeef02849bfe3b Mon Sep 17 00:00:00 2001 From: Matthias Melcher Date: Mon, 24 Mar 2025 11:26:22 +0100 Subject: Upadate macOS README. --- README.macOS.md | 254 +++++++------------------------------------------------- 1 file changed, 30 insertions(+), 224 deletions(-) diff --git a/README.macOS.md b/README.macOS.md index 686d89e24..e2157a978 100644 --- a/README.macOS.md +++ b/README.macOS.md @@ -25,15 +25,6 @@ _README.macOS.md - Building FLTK under Apple macOS_ * [Installing FLTK](#bcm_install) * [Creating new Projects](#bcm_new_projects) -* [How to Build FLTK Using _autoconf_ and _make_](#build_autoconf_make) - * [Prerequisites](#bam_prerequisites) - * [Downloading FLTK and Unpacking](#bam_download) - * [Configuring FLTK](#bam_config) - * [Building FLTK](#bam_build) - * [Testing FLTK](#bam_test) - * [Installing FLTK](#bam_install) - * [Creating new Projects](#bam_new_projects) - * [Make an Application Launchable by Dropping Files on its Icon](#dropstart) * [Document History](#doc_history) @@ -42,15 +33,14 @@ _README.macOS.md - Building FLTK under Apple macOS_ ## Introduction FLTK supports macOS version 10.3 Panther and above. At the time of writing (Feb. 2022), -FLTK compiles and runs fine on the most recent macOS 12 Monterey for both Intel and -the new M1 Apple Silicon (Arm) processors. +FLTK compiles and runs fine on the most recent macOS 12 Monterey for both Intel +processors and Apple Silicon. -FLTK 1.4 supports the following build environments on the macOS +FLTK 1.5 supports the following build environments on the macOS platform: * [_cmake_ and _Xcode_](#build_cmake_xcode), no shell needed * [_cmake_ and _make_](#build_cmake_make) from the command line -* [_autoconf_ and _make_](#build_autoconf_make) from the command line All environments will generate Unix style static libraries and macOS style app bundles. @@ -84,7 +74,7 @@ the Finder window opens, drag the _CMake_ icon into the Applications folder. ### Downloading FLTK and Unpacking (CMake, Xcode) -FLTK 1.4 is currently (as of May 2021) available as a source code repository via GitHub. +FLTK 1.5 is currently (as of Mar 2025) available as a source code repository via GitHub. You will need to clone the repository to check out the source code onto your machine. This has the great benefit that the source code can be updated later simply by telling _git_ to _pull_ the newest release. @@ -94,7 +84,7 @@ Weekly snapshots ("tarballs") can be downloaded from https://www.fltk.org/softwa If you want to use _Xcode_ to clone the FLTK GitHub repository, you will have to give _Xcode_ access to your GitHub Account in the _Xcode_ preferences. If you don't have a GitHub account, or don't want to share your credentials with _Xcode_, you can use still the command -line `git clone https://github.com/fltk/fltk.git fltk-1.4` +line `git clone https://github.com/fltk/fltk.git fltk-1.5` to check out the repo. Start _Xcode_. Select `Source Control >> Clone...` in the main menu. @@ -104,7 +94,7 @@ the search field. A list of matching repositories appears. The first one should and be owned by `fltk`. Select it and click _Clone_. A file chooser appears. Navigate to your home directory. Create a new folder named -`dev`. Enter `fltk-1.4` in the _Save As:_ field and click _Clone_, then _Done_ in the +`dev`. Enter `fltk-1.5` in the _Save As:_ field and click _Clone_, then _Done_ in the previous dialog. The local copy of your repository can be updated by loading it into _Xcode_ and selecting @@ -117,23 +107,23 @@ Launch _CMake_ by pressing Command+Spacebar, then type _CMake_ and press return. _CMake_ should open with a large dialog box. The first input field is labeled with _Where is the source code:_ . Click on _Browse Source..._ -and navigate to your home folder, then `dev`, then `fltk-1.4`. Click _Open_. +and navigate to your home folder, then `dev`, then `fltk-1.5`. Click _Open_. The next input field is marked _Where to build the binaries:_. Click _Browse Build..._ -and navigate to your home folder, then `dev`, then `fltk-1.4`, then use _New Folder_ +and navigate to your home folder, then `dev`, then `fltk-1.5`, then use _New Folder_ to create a folder named `build`, and inside that, create a folder named `Xcode`. Click _Open_. The top two input fields should read ``` -/Users/your_name/dev/fltk-1.4 +/Users/your_name/dev/fltk-1.5 ``` and ``` -/Users/your_name/dev/fltk-1.4/build/Xcode +/Users/your_name/dev/fltk-1.5/build/Xcode ``` Back in the _CMake_ main window, click _Configure_, select _Xcode_ as the generator and -click _Done_. _CMake_ will now analyse your system and find tools and dependencies. When +click _Done_. _CMake_ will now analyze your system and find tools and dependencies. When done, the upper list field in _CMake_ will show CMAKE and FLTK. Open the FLTK field and adjust options if you like. Note that the bundled image libraries are built by default. Further options are available under the CMAKE field. @@ -153,7 +143,7 @@ _CMake_ will be smart enough to update the build files as well. Now this is easy if all the previous steps were successful. If you are still in _CMake_, just click _Open Project_ and _CMake_ will launch _XCode_ for you. If not, just launch _XCode_ and -open `Macintosh HD⁩ ▸ ⁨Users⁩ ▸ your_name⁩ ▸ ⁨dev⁩ ▸ ⁨fltk-1.4⁩ ▸ ⁨build⁩ ▸ ⁨Xcode⁩ ▸ ⁨FLTK.xcodeproj`. +open `Macintosh HD⁩ ▸ ⁨Users⁩ ▸ your_name⁩ ▸ ⁨dev⁩ ▸ ⁨fltk-1.5 ▸ ⁨build⁩ ▸ ⁨Xcode⁩ ▸ ⁨FLTK.xcodeproj`. _XCode_ may or may not ask to Autocreate Schemes. Click _Automatically Create Schemes_. @@ -184,9 +174,9 @@ See README.CMake.txt ## How to Build FLTK Using _CMake_ and _make_ -This option is best for users who like to develop their apps without using Apple's Xcode IDE, -but like the advantages of _CMake_ over _autoconf_. Users should be comfortable with -using `bash` or `tcsh` in a terminal window. +This option is best for users who like to develop their apps without using +Apple's Xcode IDE. Users should be comfortable with using `bash` or `tcsh` in +a terminal window. This option requires neither administrator rights, nor an Apple ID. @@ -234,20 +224,10 @@ Downloading FLTK is explained [here](#bam_download). Using your shell in the terminal, make sure that you are in the root directory of your FLTK source code tree. -Create a directory where all FLTK binaries will be built: - -```bash -mkdir build -cd build -mkdir Makefile -cd Makefile -``` -Now configure your FLTK installation: +Configure your FLTK installation. CMake will create the required directories for you: ```bash -cmake -G "Unix Makefiles" \ - -D CMAKE_BUILD_TYPE=Debug \ - ../.. +cmake -B build/Makefile -G "Unix Makefiles" -D CMAKE_BUILD_TYPE=Debug . ``` Replace 'Debug' with 'Release' if you want to build a release version. @@ -256,31 +236,37 @@ _CMake_ runs a number of tests to find external headers, libraries, and tools. The configuration summary should not show any errors. You can now continue to build FLTK. For the advanced user there are a few more options to the _CMake_ setup. Type -`cmake -L ../..` to get a complete list of options. These should be pretty +`cmake -L .` to get a complete list of options. These should be pretty self-explanatory. Some more details can be found in [online documentation](https://www.fltk.org/doc-1.5/intro.html#intro_cmake). ### Building FLTK (CMake, make) -Now this is easy if all the previous steps were successful. Stay in your `build/Makefiles` -directory and type: +Now this is easy if all the previous steps were successful. Stay in the root +directory of your FLTK source code tree and type: ```bash -make +cmake --build build/Makefile ``` The entire FLTK toolkit including many test programs will be built for you. No warnings should appear, but "ranlib" may complain about a few modules having no symbols. This is normal and can safely be ignored. +To build individual targets, you can use: + +```bash +cmake --build build/Makefile --target hello +``` + ### Testing FLTK (CMake, make) After a successful build, you can test FLTK's capabilities by running ```bash -open bin/test/demo.app +open build/Makefile/bin/test/demo.app ``` @@ -290,7 +276,7 @@ If you did not change any of the configuration settings, FLTK will be installed in `/usr/local/include`, `/usr/local/lib`, and `/usr/local/bin` by typing ```bash -sudo make install +sudo cmake --build build/Makefile --target install ``` It is possible to install FLTK without superuser privileges by changing the @@ -315,187 +301,6 @@ fltk-config --compile myProgram.cxx `PATH` variable. - -## How to Build FLTK Using _autoconf_ and _make_ - -This option is best for users who like to develop their apps without using Apple's Xcode IDE -and prefer minimal dependencies of a _Makefile_ over _CMake_. Users should be comfortable -with using `bash` or `tcsh` in a terminal window. - -This option requires administrator rights, but no Apple ID. - - -### Prerequisites (autoconf, make) - -In order to build FLTK from the command line, you need to install a C++ compiler -environment, `make` and `autoconf`. Installing the _Xcode_ command line tools is the easiest -way to get all prerequisites in one simple step. - - -Launch _Terminal.app_ by pressing Command+Spacebar and typing `Terminal` and pressing _return_. -I like to keep the Terminal in the Dock for future use (launch Terminal, right-click or control-click -on the Terminal icon that is now in the docking bar, and choose _Options_->_Keep in Dock_). - -Installing the _Xcode_ command line tools is pretty straight forward. Just enter this -and follow the dialogs: - -```bash -xcode-select --install -``` - -On older versions of macOS, you will have to install _Xcode_ from the -[App Store](https://itunes.apple.com/de/app/xcode/id497799835?l=en&mt=12) -and then install the command line tools from within _Xcode_. - -Apple no longer includes _autoconf_ in the _Xcode_ command line tools. To install -_autoconf_, we first need to install _brew_ by typing this rather cryptic command in the shell -(you will need to type the password of an administrator account): - -```bash -ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" -``` - -After a few minutes, we can now build and install all other tools from one simple command: - -```bash -brew install autoconf -``` - -Alternatively, _autoconf_ can be installed without _brew_ as follows : - -- Download file _autoconf-latest.tar.gz_ from the autoconf ftp site -- Uncompress it to get directory _autoconf-x.xx/_ (where x's indicate autoconf's version number) -- Set this directory as your current directory in the Terminal app and type : - -```bash -./configure -make -sudo make install -``` - - - -### Downloading and Unpacking (autoconf, make) - -FLTK 1.4 is currently (as of May 2021) available as a source code repository via GitHub. -You will need to clone the repository to check out the source code onto your machine. This -has the great benefit that the source code can be updated later simply by telling _git_ to -_pull_ the newest release. - -As an alternative weekly snapshots ("tarballs") can be downloaded from -https://www.fltk.org/software.php . - -Start your terminal. If you have not set up a developer directory yet, I recommend to use -`~/dev` and put all your projects there: - -```bash -# make sure we are in the home directory -cd ~ -# create our developer directory and go there -mkdir dev -cd dev -``` -Now create a copy of the source code archive at Github on your local file system: - -```bash -git clone https://github.com/fltk/fltk.git fltk-1.4 -cd fltk-1.4 -``` - - -### Configuring FLTK (autoconf, make) - -Using your shell in the terminal, make sure that you are in the root directory of your -FLTK source code tree. - -If you are configuring fltk for the first time, you need to instruct FLTK to create some -very basic configuration files. Type: - -```bash -autoconf -``` -This creates the configure script. - -Now configure your FLTK installation. Stay in your FLTK source-code directory -and type - -```bash -./configure -``` - -The configuration script runs a number of tests to find external headers, libraries, and tools. -The configuration summary should not show any errors. You can now continue to build FLTK. - -For the advanced user there are a few more options to the _configure_ script. Type -`./configure --help` to get a complete list of options. These should be pretty -self-explanatory. Some more details can be found in -[online documentation](https://www.fltk.org/doc-1.5/intro.html#intro_cmake). - - -### Building FLTK (autoconf, make) - -Now this is easy if all the previous steps were successful. Stay in your FLTK source-code -directory and type: - -```bash -make -``` - -The entire FLTK toolkit including many test programs will be built for you. No -warnings should appear, but "ranlib" may complain about a few modules having no -symbols. This is normal and can safely be ignored. - - -### Testing FLTK (autoconf, make) - -After a successful build, you can test FLTK's capabilities by running - -```bash -test/demo -``` - - -### Installing FLTK (autoconf, make) - -If you did not change any of the configuration settings, FLTK will be installed -in `/usr/local/include`, `/usr/local/lib`, and `/usr/local/bin` by typing: - -```bash -sudo make install -``` - -It is possible to install FLTK without superuser privileges by changing the -installation path to a location within the user account by adding the -`--prefix=PREFIX` parameter to the `./configure` command. - - -### Creating new Projects (autoconf, make) - -FLTK provides a neat script named `fltk-config` that can provide all the flags -needed to build FLTK applications using the same flags that were used to build -the library itself. Running `fltk-config` without arguments will print a list -of options. The easiest call to compile an FLTK application from a single source -file is: - -```bash -cat << EOF > main.cxx - #include - #include - int main(int argc, char **argv) { - Fl_Window *win = new Fl_Window(600, 400, "Hello, world!"); - win->show(argc, argv); - return Fl::run(); - } -EOF -fltk-config --compile main.cxx -./main -``` - -`fltk-config` and our user interface designer `fluid` will be installed in -`/usr/local/bin/` by default. I recommend that you add this directory to the shell -`PATH` variable. - - ## Make an Application Launchable by Dropping Files on its Icon @@ -535,3 +340,4 @@ to the Info.plist file you have prepared. - Dec 28 2018 - Matt: complete rework for FLTK 1.4 - Mar 01 2021 - Albrecht: minor updates, macOS Big Sur and Apple Silicon M1 (ARM) - Feb 23 2022 - Manolo: install autoconf without brew +- Mar 22 2025 - Matt: update for FLTK 1.5 -- cgit v1.2.3 From d756076644c16cb74051fa7520f84375263b84c4 Mon Sep 17 00:00:00 2001 From: ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> Date: Tue, 25 Mar 2025 17:31:25 +0100 Subject: Fix: Windows: Clipboard gets stuck when text is copied while window is hidden (#1233) --- src/drivers/WinAPI/Fl_WinAPI_Window_Driver.cxx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/drivers/WinAPI/Fl_WinAPI_Window_Driver.cxx b/src/drivers/WinAPI/Fl_WinAPI_Window_Driver.cxx index 552f26dfc..88eb2cdca 100644 --- a/src/drivers/WinAPI/Fl_WinAPI_Window_Driver.cxx +++ b/src/drivers/WinAPI/Fl_WinAPI_Window_Driver.cxx @@ -441,6 +441,7 @@ void Fl_WinAPI_Window_Driver::label(const char *name,const char *iname) { extern void fl_clipboard_notify_retarget(HWND wnd); extern void fl_update_clipboard(void); +extern char fl_i_own_selection[2]; void Fl_WinAPI_Window_Driver::hide() { Fl_X* ip = Fl_X::flx(pWindow); @@ -474,6 +475,8 @@ void Fl_WinAPI_Window_Driver::hide() { // Issue #569: undo RegisterDragDrop() RevokeDragDrop((HWND)ip->xid); + + fl_i_own_selection[1] = 0; // issue #1233 // make sure any custom icons get freed // icons(NULL, 0); // free_icons() is called by the Fl_Window destructor -- cgit v1.2.3 From 8424af743b2ccbc0cabd584216627bed7baad4af Mon Sep 17 00:00:00 2001 From: Albrecht Schlosser Date: Mon, 24 Mar 2025 17:02:05 +0100 Subject: Disallow in-source builds Rationale: 1. Building in-source creates a lot of untracked files in the source tree. We need to take care not to commit any of them, hence we have to maintain .gitignore files in several directories. 2. Tests reveal that there are even files in git that are modified in the source tree when building docs etc. which means e.g. that builds can't be "repeated" after upgrading the sources, and that those files could be committed by accident. To avoid this we'd have to reorganize the build procedure and make it even more complex rather than simplifying it. 3. With autoconf/configure/make we didn't have a choice, i.e. we had to allow in-source builds with configure/Makefiles anyway. This is no longer true since we removed configure/make support. Note, todo: if this commit doesn't introduce unexpected issues, then we can remove a lot of stuff from the .gitignore files, but this is left for a later commit. --- CMakeLists.txt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 420e379c1..08548b2b4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,23 @@ # https://www.fltk.org/bugs.php # +####################################################################### +# Prevent building in the source tree - don't pollute the sources +####################################################################### + +if("${CMAKE_BINARY_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}") + message("") + message(STATUS "=======================================================================") + message(STATUS " NOTE: In-source builds of FLTK are disabled to prevent writing to the") + message(STATUS " NOTE: source tree. Please create a subfolder (e.g. 'build') and use") + message(STATUS " NOTE: `cmake ..` inside it or use for instance `cmake . -B build`.") + message(STATUS " NOTE: CMake will, however, create CMakeCache.txt and CMakeFiles/* .") + message(STATUS " NOTE: You must delete CMakeCache.txt and CMakeFiles/* manually.") + message(STATUS "=======================================================================") + message("") + message(FATAL_ERROR "*** In-source builds are disabled, please read notes above! ***") +endif() + ####################################################################### # Set CMake minimum version first: must be set before `project()` ####################################################################### -- cgit v1.2.3 From 6db6a9d8b851dfa5a9a379a8aa9ac516aa6e19d2 Mon Sep 17 00:00:00 2001 From: Albrecht Schlosser Date: Thu, 27 Mar 2025 15:04:55 +0100 Subject: Remove reference to 'configure' from comment Explain details of the mentioned 'hack' referring to and citing parts of the original commit log. --- src/fl_write_png.cxx | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/fl_write_png.cxx b/src/fl_write_png.cxx index 0f980476a..855e03551 100644 --- a/src/fl_write_png.cxx +++ b/src/fl_write_png.cxx @@ -1,7 +1,7 @@ // // Fl_PNG_Image support functions for the Fast Light Tool Kit (FLTK). // -// Copyright 2005-2021 by Bill Spitzak and others. +// Copyright 2005-2025 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -18,9 +18,16 @@ #include #include #include -#include // fl_fopen() +#include // fl_fopen() #include -#include // hack to restore "configure --enable-x11" on macOS ≥ 11 + +// FIXME: see original commit 2db94dcb4c5bf2ef3fa92f1cd6a41f3f90105361 +// ... about building X11 backend on macOS ≥ 11: +// "The error happens only if png.h is included without time.h having +// been included before. The fix is to #include time.h before png.h. +// A better fix than his hack is desirable." + +#include // PNG library include files -- cgit v1.2.3 From 1f715f8766d3a325c15ef59eebfec1dbc32b09d3 Mon Sep 17 00:00:00 2001 From: Albrecht Schlosser Date: Thu, 27 Mar 2025 16:14:29 +0100 Subject: Update fltk-config.in (minor comment changes only) --- fltk-config.in | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fltk-config.in b/fltk-config.in index ee16204b5..c23b79ce6 100644 --- a/fltk-config.in +++ b/fltk-config.in @@ -2,7 +2,7 @@ # # FLTK configuration utility. # -# Copyright 2000-2024 by Bill Spitzak and others. +# Copyright 2000-2025 by Bill Spitzak and others. # Original version Copyright 2000 by James Dean Palmer # Adapted by Vincent Penne and Michael Sweet # @@ -17,7 +17,7 @@ # https://www.fltk.org/bugs.php # -# Variables and constants generated by configure or CMake: +# Variables and constants generated by CMake: # version numbers MAJOR_VERSION=@FLTK_VERSION_MAJOR@ @@ -41,7 +41,7 @@ OPTIM="@OPTIM@" CAIROFLAGS="@CAIROFLAGS@" # BINARY_DIR: this is only set for CMake builds in the CMake build directory, -# otherwise it is an empty string +# otherwise it is an empty string (for instance in the install directory) BINARY_DIR=@BINARY_DIR@ prefix="@prefix@" @@ -121,7 +121,7 @@ Options telling what information we request: [--cxxflags] return flags to compile C++ using FLTK [--ldflags] return flags to link against FLTK [--ldstaticflags] return flags to link against static FLTK library - even if there are DSOs installed + even if there are DSOs installed [--libs] return FLTK libraries full path for dependencies [--prefix] return FLTK install time --prefix directory [--includedir] return FLTK install time include directory -- cgit v1.2.3 From 9e1e043af35e979f5ad0824fb74f6e7fab57be7d Mon Sep 17 00:00:00 2001 From: Greg Ercolano Date: Fri, 28 Mar 2025 12:54:16 -0700 Subject: Changed two connector methods to virtual For reference, see fltk.general thread started Mar 26 2025, entitled: "Make some Fl_Tree_Item methods virtual?" --- FL/Fl_Tree_Item.H | 4 ++-- src/Fl_Tree_Item.cxx | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/FL/Fl_Tree_Item.H b/FL/Fl_Tree_Item.H index b76395334..8cdd6ee10 100644 --- a/FL/Fl_Tree_Item.H +++ b/FL/Fl_Tree_Item.H @@ -93,8 +93,8 @@ protected: void _Init(const Fl_Tree_Prefs &prefs, Fl_Tree *tree); void show_widgets(); void hide_widgets(); - void draw_vertical_connector(int x, int y1, int y2, const Fl_Tree_Prefs &prefs); - void draw_horizontal_connector(int x1, int x2, int y, const Fl_Tree_Prefs &prefs); + virtual void draw_vertical_connector(int x, int y1, int y2, const Fl_Tree_Prefs &prefs); + virtual void draw_horizontal_connector(int x1, int x2, int y, const Fl_Tree_Prefs &prefs); void recalc_tree(); int calc_item_height(const Fl_Tree_Prefs &prefs) const; Fl_Color drawfgcolor() const; diff --git a/src/Fl_Tree_Item.cxx b/src/Fl_Tree_Item.cxx index 616a77392..5234bbd3c 100644 --- a/src/Fl_Tree_Item.cxx +++ b/src/Fl_Tree_Item.cxx @@ -705,7 +705,8 @@ int Fl_Tree_Item::swap_children(Fl_Tree_Item *a, Fl_Tree_Item *b) { return(0); } -/// Internal: Horizontal connector line based on preference settings. +/// Horizontal connector line based on preference settings. +/// This method can be overridden to implement custom connection line drawing. /// \param[in] x1 The left hand X position of the horizontal connector /// \param[in] x2 The right hand X position of the horizontal connector /// \param[in] y The vertical position of the horizontal connector @@ -730,7 +731,8 @@ void Fl_Tree_Item::draw_horizontal_connector(int x1, int x2, int y, const Fl_Tre } } -/// Internal: Vertical connector line based on preference settings. +/// Vertical connector line based on preference settings. +/// This method can be overridden to implement custom connection line drawing. /// \param[in] x The x position of the vertical connector /// \param[in] y1 The top of the vertical connector /// \param[in] y2 The bottom of the vertical connector -- cgit v1.2.3 From cb86a37676e26a8de209a371132d8154986b457a Mon Sep 17 00:00:00 2001 From: Albrecht Schlosser Date: Sat, 29 Mar 2025 21:03:18 +0100 Subject: Allow FL_ABI_VERSION = FL_API_VERSION + 1 ... so users can enable ABI features designated for the *next* release when using FLTK from Git (or snapshots) before the API version has been raised for that release. --- FL/Enumerations.H | 14 +++++++++----- README.abi-version.txt | 5 +++++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/FL/Enumerations.H b/FL/Enumerations.H index 1a8b219bd..2478a8c58 100644 --- a/FL/Enumerations.H +++ b/FL/Enumerations.H @@ -153,11 +153,15 @@ This is done to prevent users from defining an illegal ABI version. Rule: FL_MAJOR_VERSION * 10000 + FL_MINOR_VERSION * 100 - <= FL_ABI_VERSION <= FL_API_VERSION. + <= FL_ABI_VERSION <= FL_API_VERSION + 1. - Example (FLTK 1.3.4): + Since FLTK 1.4.2+ (Git commits after release 1.4.2) FL_ABI_VERSION is + allowed to be one higher than FL_API_VERSION so ABI changes in Git + targeted at the *next* release (e.g. 1.4.3) can be used. - 10300 <= FL_ABI_VERSION <= 10304 + Example: Commits after release FLTK 1.4.2 (before release 1.4.3): + + 10400 <= FL_ABI_VERSION <= 10403 Note: configure + CMake can be used to define FL_ABI_VERSION, but they do not check validity. This is done here. @@ -168,10 +172,10 @@ # undef FL_ABI_VERSION # define FL_ABI_VERSION (FL_MAJOR_VERSION*10000 + FL_MINOR_VERSION*100) -#elif FL_ABI_VERSION > FL_API_VERSION +#elif FL_ABI_VERSION > FL_API_VERSION + 1 # undef FL_ABI_VERSION -# define FL_ABI_VERSION FL_API_VERSION +# define FL_ABI_VERSION FL_API_VERSION + 1 #endif diff --git a/README.abi-version.txt b/README.abi-version.txt index f6a87019f..10729a959 100644 --- a/README.abi-version.txt +++ b/README.abi-version.txt @@ -45,6 +45,11 @@ The default ABI version is always the lowest version (e.g. 10400). All following examples are written for FLTK 1.4.1, hence we use "10401" for the version number. +Note: Since FLTK 1.4.3 (Git branch-1.4 after release 1.4.2) the highest +selectable ABI version is FL_API_VERSION + 1 so you can use ABI features +designated for the *next* FLTK release when using FLTK from Git with new +ABI features included for the next release. + How to select the ABI version with CMake ---------------------------------------- -- cgit v1.2.3 From b7189192e2e31ce5ca1f2eaac2a303f9b8216ded Mon Sep 17 00:00:00 2001 From: Matthias Melcher Date: Sat, 29 Mar 2025 22:40:13 +0100 Subject: Adds a new event FL_TOOLTIP_EVENT... ... and Fl_Tootip::override_text() to allow users to dynamically generate tooltips. --- FL/Enumerations.H | 6 +++- FL/Fl_Tooltip.H | 12 +++++--- FL/names.h | 5 ++-- src/Fl_Tooltip.cxx | 81 +++++++++++++++++++++++++++++++++++++++----------- test/color_chooser.cxx | 20 ++++++++++++- 5 files changed, 98 insertions(+), 26 deletions(-) diff --git a/FL/Enumerations.H b/FL/Enumerations.H index 2478a8c58..db6465096 100644 --- a/FL/Enumerations.H +++ b/FL/Enumerations.H @@ -414,7 +414,11 @@ enum Fl_Event { // events /** A zoom event (ctrl/+/-/0/ or cmd/+/-/0/) was processed. Use Fl::add_handler() to be notified of this event. */ - FL_ZOOM_EVENT = 27 + FL_ZOOM_EVENT = 27, + /** A tooltip is about to pop up for this widget. The mouse coordinates are + available in Fl::event_x() and Fl::event_y(). Change the widget tooltip + as needed. */ + FL_TOOLTIP_EVENT = 28 // DEV NOTE: Keep this list in sync with FL/names.h }; diff --git a/FL/Fl_Tooltip.H b/FL/Fl_Tooltip.H index b79d93149..d417ba189 100644 --- a/FL/Fl_Tooltip.H +++ b/FL/Fl_Tooltip.H @@ -95,6 +95,8 @@ public: static void wrap_width(int v) { wrap_width_ = v; } /** Returns the window that is used for tooltips */ static Fl_Window* current_window(void); + /** \brief Temporarily Override Tooltip Text during an FL_TOOLTIP_EVENT. */ + static int override_text(const char *new_text); // These should not be public, but Fl_Widget::tooltip() needs them... // fabien: made it private with only a friend function access @@ -104,20 +106,22 @@ private: static void enter_(Fl_Widget* w); static void exit_(Fl_Widget *w); static void set_enter_exit_once_(); + static void tooltip_timeout_(void*); private: - static float delay_; //!< delay before a tooltip is shown - static float hidedelay_; //!< delay until tooltip is closed again - static float hoverdelay_; //!< delay between tooltips + static float delay_; //!< delay before a tooltip is shown + static float hidedelay_; //!< delay until tooltip is closed again + static float hoverdelay_; //!< delay between tooltips static Fl_Color color_; static Fl_Color textcolor_; static Fl_Font font_; static Fl_Fontsize size_; - static Fl_Widget* widget_; //!< Keeps track of the current target widget + static Fl_Widget* widget_; //!< Keeps track of the current target widget static int margin_width_; //!< distance around tooltip text left+right static int margin_height_; //!< distance around tooltip text top+bottom static int wrap_width_; //!< maximum width of tooltip text before it word wraps static const int draw_symbols_; // 1 = draw @-symbols in tooltips, 0 = no + static char *override_text_; //!< a copy of the last text for an overridden tooltip }; #endif diff --git a/FL/names.h b/FL/names.h index 984afbfe0..e47d005ec 100644 --- a/FL/names.h +++ b/FL/names.h @@ -73,9 +73,10 @@ const char * const fl_eventnames[] = "FL_FULLSCREEN", "FL_ZOOM_GESTURE", "FL_ZOOM_EVENT", - "FL_EVENT_28", // not yet defined, just in case it /will/ be defined ... + "FL_TOOLTIP_EVENT", "FL_EVENT_29", // not yet defined, just in case it /will/ be defined ... - "FL_EVENT_30" // not yet defined, just in case it /will/ be defined ... + "FL_EVENT_30", // not yet defined, just in case it /will/ be defined ... + "FL_EVENT_31" // not yet defined, just in case it /will/ be defined ... }; /** diff --git a/src/Fl_Tooltip.cxx b/src/Fl_Tooltip.cxx index 674c57a49..f80956039 100644 --- a/src/Fl_Tooltip.cxx +++ b/src/Fl_Tooltip.cxx @@ -25,6 +25,9 @@ #include + +#define DEBUG + float Fl_Tooltip::delay_ = 1.0f; float Fl_Tooltip::hidedelay_ = 12.0f; float Fl_Tooltip::hoverdelay_ = 0.2f; @@ -38,6 +41,7 @@ int Fl_Tooltip::margin_width_ = 3; int Fl_Tooltip::margin_height_ = 3; int Fl_Tooltip::wrap_width_ = 400; const int Fl_Tooltip::draw_symbols_ = 1; +char *Fl_Tooltip::override_text_ = nullptr; static const char* tip; @@ -154,14 +158,49 @@ static void tooltip_hide_timeout(void*) { recent_tooltip = 0; } -static void tooltip_timeout(void*) { +/** + Use this method to temporarily change the tooltip text before it is displayed. + + When FLTK sends an FL_TOOLTIP_EVENT to the widget under the mouse pointer, + you can handle this event to modify the tooltip text dynamically. The + provided text will be copied into a local buffer. To apply the override, + the event handler must return 1. + + To disable the tooltip for the current event, set the override text to nullptr + or an empty string ("") and return 1. + + \param[in] new_text a C string that will be copied into a buffer + \return always 1, so this call can finish the FL_TOOLTIP_EVENT handling. + + \see void Fl_Widget::tooltip(const char *text). + + \see `test/color_chooser.cxx` for a usage example. +*/ +int Fl_Tooltip::override_text(const char *new_text) { + if (new_text != override_text_) { + if (window && window->label()==override_text_) + ((Fl_Widget *) window)->label(nullptr); + if (override_text_) + ::free(override_text_); + override_text_ = nullptr; + if (new_text) + override_text_ = ::strdup(new_text); + } + return 1; +} + +void Fl_Tooltip::tooltip_timeout_(void*) { #ifdef DEBUG - puts("tooltip_timeout();"); + puts("tooltip_timeout_();"); #endif // DEBUG if (recursion) return; recursion = 1; if (!top_win_iconified_()) { // no tooltip if top win iconified (STR #3157) + if (Fl_Tooltip::current()) { + if (Fl_Tooltip::current()->handle(FL_TOOLTIP_EVENT)) + tip = Fl_Tooltip::override_text_; + } if (!tip || !*tip) { if (window) window->hide(); Fl::remove_timeout(tooltip_hide_timeout); @@ -253,7 +292,7 @@ void Fl_Tooltip::exit_(Fl_Widget *w) { if (!widget_ || (w && w == window)) return; widget_ = 0; - Fl::remove_timeout(tooltip_timeout); + Fl::remove_timeout(tooltip_timeout_); Fl::remove_timeout(recent_timeout); if (window && window->visible()) { window->hide(); @@ -298,7 +337,7 @@ void Fl_Tooltip::enter_area(Fl_Widget* wid, int x,int y,int w,int h, const char* } // do nothing if it is the same: if (wid==widget_ /*&& x==X && y==currentTooltipY && w==W && h==currentTooltipH*/ && t==tip) return; - Fl::remove_timeout(tooltip_timeout); + Fl::remove_timeout(tooltip_timeout_); Fl::remove_timeout(recent_timeout); // remember it: widget_ = wid; currentTooltipY = y; currentTooltipH = h; tip = t; @@ -308,7 +347,7 @@ void Fl_Tooltip::enter_area(Fl_Widget* wid, int x,int y,int w,int h, const char* window->hide(); Fl::remove_timeout(tooltip_hide_timeout); } - Fl::add_timeout(Fl_Tooltip::hoverdelay(), tooltip_timeout); + Fl::add_timeout(Fl_Tooltip::hoverdelay(), tooltip_timeout_); } else if (Fl_Tooltip::delay() < .1) { // possible fix for the Windows titlebar, it seems to want the // window to be destroyed, moving it messes up the parenting: @@ -316,13 +355,13 @@ void Fl_Tooltip::enter_area(Fl_Widget* wid, int x,int y,int w,int h, const char* window->hide(); Fl::remove_timeout(tooltip_hide_timeout); } - tooltip_timeout(0); + tooltip_timeout_(nullptr); } else { if (window && window->visible()) { window->hide(); Fl::remove_timeout(tooltip_hide_timeout); } - Fl::add_timeout(Fl_Tooltip::delay(), tooltip_timeout); + Fl::add_timeout(Fl_Tooltip::delay(), tooltip_timeout_); } #ifdef DEBUG @@ -341,19 +380,25 @@ void Fl_Tooltip::set_enter_exit_once_() { } /** - Sets the current tooltip text. + Sets the Tooltip Text for a Widget. - Sets a string of text to display in a popup tooltip window when the user - hovers the mouse over the widget. The string is not copied, so - make sure any formatted string is stored in a static, global, - or allocated buffer. If you want a copy made and managed for you, - use the copy_tooltip() method, which will manage the tooltip string - automatically. + Assigns a tooltip string that appears in a popup when the user hovers over + the widget. The provided string is not copied. The caller must eensure it + remains valid by storing it in a static, global, or dynamically allocated + buffer. If you need the tooltip string to be copied and managed automatically, + use copy_tooltip(). + + By default, a widget inherits the tooltip of its parent if none is explicitly + set. If you assign a tooltip to a group but not to its child widgets, the + child widgets will display the group’s tooltip. To prevent inheritance, set + the child’s tooltip to an empty string (""). + + Tooltips can be updated dynamically before they are displayed. When a tooltip + is about to be shown, FLTK sends an `FL_TOOLTIP_EVENT` to the widget’s + `handle()` method. Developers can override the tooltip text temporarily + using `Fl_Tooltip::override_text(const char* new_text)` and returning 1 from + `handle()` to apply the change. - If no tooltip is set, the tooltip of the parent is inherited. Setting a - tooltip for a group and setting no tooltip for a child will show the - group's tooltip instead. To avoid this behavior, you can set the child's - tooltip to an empty string (""). \param[in] text New tooltip text (no copy is made) \see copy_tooltip(const char*), tooltip() */ diff --git a/test/color_chooser.cxx b/test/color_chooser.cxx index 61fbc4caf..a9a7a5ca1 100644 --- a/test/color_chooser.cxx +++ b/test/color_chooser.cxx @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -84,6 +85,22 @@ void cb2(Fl_Widget *, void *v) { bx->parent()->redraw(); } +class Image_Box: public Fl_Box { +public: + Image_Box(int x, int y, int w, int h, const char *label = nullptr) + : Fl_Box(x, y, w, h, label) { } + int handle(int event) { + if (event == FL_TOOLTIP_EVENT) { + const char *color_name_lut[] = { "blue", "green", "black", "red" }; + int quadrant = (Fl::event_x() < x()+w()/2) + 2*(Fl::event_y() < y()+h()/2); + char buf[80]; + ::snprintf(buf, 79, "Color %s at x=%d, y=%d", color_name_lut[quadrant], Fl::event_x(), Fl::event_y()); + return Fl_Tooltip::override_text(buf); + } + return Fl_Box::handle(event); + } +}; + int main(int argc, char ** argv) { Fl::set_color(fullcolor_cell,145,159,170); Fl_Window window(400,400); @@ -98,7 +115,8 @@ int main(int argc, char ** argv) { b1.callback(cb1,&box); Fl_Button b2(120,120,180,30,"fl_color_chooser()"); b2.callback(cb2,&box); - Fl_Box image_box(160,190,width,height,0); + Image_Box image_box(160,190,width,height,0); + image_box.tooltip("Image Box"); make_image(); (new Fl_RGB_Image(image, width, height))->label(&image_box); Fl_Box b(160,310,120,30,"Example of fl_draw_image()"); -- cgit v1.2.3 From 5dd1062df53c747339b875c8cb0c13df576ad4b8 Mon Sep 17 00:00:00 2001 From: Matthias Melcher Date: Sat, 29 Mar 2025 23:36:09 +0100 Subject: Adding `FL_BEFORE_MENU` event to classes derived from `Fl_Menu_` --- FL/Enumerations.H | 6 +++++- FL/Fl_Choice.H | 4 ++++ FL/Fl_Menu_Bar.H | 4 ++++ FL/Fl_Menu_Button.H | 4 ++++ FL/Fl_Tooltip.H | 2 +- FL/names.h | 7 ++++--- src/Fl_Choice.cxx | 2 ++ src/Fl_Input_Choice.cxx | 5 +++++ src/Fl_Menu_Bar.cxx | 2 ++ src/Fl_Menu_Button.cxx | 1 + src/Fl_Tooltip.cxx | 14 +++++++------- test/color_chooser.cxx | 2 +- test/menubar.cxx | 31 +++++++++++++++++++++++++++++-- 13 files changed, 69 insertions(+), 15 deletions(-) diff --git a/FL/Enumerations.H b/FL/Enumerations.H index db6465096..5bc2951aa 100644 --- a/FL/Enumerations.H +++ b/FL/Enumerations.H @@ -418,7 +418,11 @@ enum Fl_Event { // events /** A tooltip is about to pop up for this widget. The mouse coordinates are available in Fl::event_x() and Fl::event_y(). Change the widget tooltip as needed. */ - FL_TOOLTIP_EVENT = 28 + FL_BEFORE_TOOLTIP = 28, + /** Triggered just before a menu is displayed. Widgets derived from Fl_Menu_ + receive this event right before the menu appears, providing an opportunity + to update menu item states and activation. */ + FL_BEFORE_MENU = 29 // DEV NOTE: Keep this list in sync with FL/names.h }; diff --git a/FL/Fl_Choice.H b/FL/Fl_Choice.H index 944f4d3a4..2434a9ac3 100644 --- a/FL/Fl_Choice.H +++ b/FL/Fl_Choice.H @@ -100,6 +100,10 @@ } \endcode + FLTK triggers an `FL_BEFORE_MENU` event for this widget right before + displaying the menu. This event provides an opportunity to update menu + item states and activation. See `test/menubar.cxx`, class `Dynamic_Choice` + "Flip" and "Flop" for a usage example. */ class FL_EXPORT Fl_Choice : public Fl_Menu_ { protected: diff --git a/FL/Fl_Menu_Bar.H b/FL/Fl_Menu_Bar.H index 26c08539d..4e7af0d6e 100644 --- a/FL/Fl_Menu_Bar.H +++ b/FL/Fl_Menu_Bar.H @@ -61,6 +61,10 @@ Typing the shortcut() of any of the menu items will cause callbacks exactly the same as when you pick the item with the mouse. + + FLTK triggers an `FL_BEFORE_MENU` event for this widget right before + displaying the menu. This event provides an opportunity to update menu + item states and activation. */ class FL_EXPORT Fl_Menu_Bar : public Fl_Menu_ { friend class Fl_Sys_Menu_Bar_Driver; diff --git a/FL/Fl_Menu_Button.H b/FL/Fl_Menu_Button.H index 0e1036450..3f52593b4 100644 --- a/FL/Fl_Menu_Button.H +++ b/FL/Fl_Menu_Button.H @@ -52,6 +52,10 @@ is done instead, along with any userdata configured for it. The callback can determine which item was picked using value(), mvalue(), item_pathname(), etc. + + FLTK triggers an `FL_BEFORE_MENU` event for this widget right before + displaying the menu. This event provides an opportunity to update menu + item states and activation. */ class FL_EXPORT Fl_Menu_Button : public Fl_Menu_ { protected: diff --git a/FL/Fl_Tooltip.H b/FL/Fl_Tooltip.H index d417ba189..592371651 100644 --- a/FL/Fl_Tooltip.H +++ b/FL/Fl_Tooltip.H @@ -95,7 +95,7 @@ public: static void wrap_width(int v) { wrap_width_ = v; } /** Returns the window that is used for tooltips */ static Fl_Window* current_window(void); - /** \brief Temporarily Override Tooltip Text during an FL_TOOLTIP_EVENT. */ + /** \brief Temporarily Override Tooltip Text during an FL_BEFORE_TOOLTIP event. */ static int override_text(const char *new_text); // These should not be public, but Fl_Widget::tooltip() needs them... diff --git a/FL/names.h b/FL/names.h index e47d005ec..90ef231e7 100644 --- a/FL/names.h +++ b/FL/names.h @@ -73,10 +73,11 @@ const char * const fl_eventnames[] = "FL_FULLSCREEN", "FL_ZOOM_GESTURE", "FL_ZOOM_EVENT", - "FL_TOOLTIP_EVENT", - "FL_EVENT_29", // not yet defined, just in case it /will/ be defined ... + "FL_BEFORE_TOOLTIP", + "FL_BEFORE_MENU", "FL_EVENT_30", // not yet defined, just in case it /will/ be defined ... - "FL_EVENT_31" // not yet defined, just in case it /will/ be defined ... + "FL_EVENT_31", // not yet defined, just in case it /will/ be defined ... + "FL_EVENT_32" // not yet defined, just in case it /will/ be defined ... }; /** diff --git a/src/Fl_Choice.cxx b/src/Fl_Choice.cxx index e5a0276af..ac9a260cf 100644 --- a/src/Fl_Choice.cxx +++ b/src/Fl_Choice.cxx @@ -195,6 +195,7 @@ int Fl_Choice::handle(int e) { J1: if (Fl::scheme() || fl_contrast(textcolor(), FL_BACKGROUND2_COLOR) != textcolor()) { + handle(FL_BEFORE_MENU); v = menu()->pulldown(x(), y(), w(), h(), mvalue(), this); if (wp.deleted()) return 1; } else { @@ -202,6 +203,7 @@ int Fl_Choice::handle(int e) { // temporarily override the color() of this widget... Fl_Color c = color(); color(FL_BACKGROUND2_COLOR); + handle(FL_BEFORE_MENU); v = menu()->pulldown(x(), y(), w(), h(), mvalue(), this); if (wp.deleted()) return 1; color(c); diff --git a/src/Fl_Input_Choice.cxx b/src/Fl_Input_Choice.cxx index 77a7d937e..4183b3e65 100644 --- a/src/Fl_Input_Choice.cxx +++ b/src/Fl_Input_Choice.cxx @@ -54,6 +54,10 @@ - 1: the user picked a different item in the choice menu - 0: the user typed or pasted directly into the input field + FLTK triggers an `FL_BEFORE_MENU` event for this widget right before + displaying the menu. This event provides an opportunity to update menu + item states and activation. + \par Example Use of Fl_Input_Choice \code #include @@ -152,6 +156,7 @@ void Fl_Input_Choice::InputMenuButton::draw() { // Make pulldown menu appear under entire width of widget const Fl_Menu_Item* Fl_Input_Choice::InputMenuButton::popup() { + handle(FL_BEFORE_MENU); menu_end(); redraw(); Fl_Widget_Tracker mb(this); diff --git a/src/Fl_Menu_Bar.cxx b/src/Fl_Menu_Bar.cxx index b26131b01..3a7530bee 100644 --- a/src/Fl_Menu_Bar.cxx +++ b/src/Fl_Menu_Bar.cxx @@ -49,6 +49,7 @@ int Fl_Menu_Bar::handle(int event) { case FL_PUSH: v = 0; J1: + handle(FL_BEFORE_MENU); v = menu()->pulldown(x(), y(), w(), h(), v, this, 0, 1); picked(v); return 1; @@ -71,6 +72,7 @@ Fl_Menu_Bar::Fl_Menu_Bar(int X, int Y, int W, int H,const char *l) void Fl_Menu_Bar::play_menu(const Fl_Menu_Item *v) { if (v) { + handle(FL_BEFORE_MENU); v = menu()->pulldown(x(), y(), w(), h(), v, this, 0, 1); picked(v); } diff --git a/src/Fl_Menu_Button.cxx b/src/Fl_Menu_Button.cxx index 22a85f52d..5321dbf48 100644 --- a/src/Fl_Menu_Button.cxx +++ b/src/Fl_Menu_Button.cxx @@ -59,6 +59,7 @@ void Fl_Menu_Button::draw() { \see Fl_Menu_::menu_end() */ const Fl_Menu_Item* Fl_Menu_Button::popup() { + handle(FL_BEFORE_MENU); menu_end(); const Fl_Menu_Item* m; pressed_menu_button_ = this; diff --git a/src/Fl_Tooltip.cxx b/src/Fl_Tooltip.cxx index f80956039..572d763d1 100644 --- a/src/Fl_Tooltip.cxx +++ b/src/Fl_Tooltip.cxx @@ -26,7 +26,7 @@ #include -#define DEBUG +// #define DEBUG float Fl_Tooltip::delay_ = 1.0f; float Fl_Tooltip::hidedelay_ = 12.0f; @@ -161,16 +161,16 @@ static void tooltip_hide_timeout(void*) { /** Use this method to temporarily change the tooltip text before it is displayed. - When FLTK sends an FL_TOOLTIP_EVENT to the widget under the mouse pointer, - you can handle this event to modify the tooltip text dynamically. The - provided text will be copied into a local buffer. To apply the override, + When FLTK sends an FL_BEFORE_TOOLTIP event to the widget under the mouse + pointer, you can handle this event to modify the tooltip text dynamically. + The provided text will be copied into a local buffer. To apply the override, the event handler must return 1. To disable the tooltip for the current event, set the override text to nullptr or an empty string ("") and return 1. \param[in] new_text a C string that will be copied into a buffer - \return always 1, so this call can finish the FL_TOOLTIP_EVENT handling. + \return always 1, so this call can finish the FL_BEFORE_TOOLTIP event handling. \see void Fl_Widget::tooltip(const char *text). @@ -198,7 +198,7 @@ void Fl_Tooltip::tooltip_timeout_(void*) { recursion = 1; if (!top_win_iconified_()) { // no tooltip if top win iconified (STR #3157) if (Fl_Tooltip::current()) { - if (Fl_Tooltip::current()->handle(FL_TOOLTIP_EVENT)) + if (Fl_Tooltip::current()->handle(FL_BEFORE_TOOLTIP)) tip = Fl_Tooltip::override_text_; } if (!tip || !*tip) { @@ -394,7 +394,7 @@ void Fl_Tooltip::set_enter_exit_once_() { the child’s tooltip to an empty string (""). Tooltips can be updated dynamically before they are displayed. When a tooltip - is about to be shown, FLTK sends an `FL_TOOLTIP_EVENT` to the widget’s + is about to be shown, FLTK sends an `FL_BEFORE_TOOLTIP` event to the widget’s `handle()` method. Developers can override the tooltip text temporarily using `Fl_Tooltip::override_text(const char* new_text)` and returning 1 from `handle()` to apply the change. diff --git a/test/color_chooser.cxx b/test/color_chooser.cxx index a9a7a5ca1..f5c9827cc 100644 --- a/test/color_chooser.cxx +++ b/test/color_chooser.cxx @@ -90,7 +90,7 @@ public: Image_Box(int x, int y, int w, int h, const char *label = nullptr) : Fl_Box(x, y, w, h, label) { } int handle(int event) { - if (event == FL_TOOLTIP_EVENT) { + if (event == FL_BEFORE_TOOLTIP) { const char *color_name_lut[] = { "blue", "green", "black", "red" }; int quadrant = (Fl::event_x() < x()+w()/2) + 2*(Fl::event_y() < y()+h()/2); char buf[80]; diff --git a/test/menubar.cxx b/test/menubar.cxx index a5ccfc234..2aeec991c 100644 --- a/test/menubar.cxx +++ b/test/menubar.cxx @@ -210,7 +210,7 @@ void menu_location_cb(Fl_Widget* w, void* data) if (((Fl_Choice*)w)->value() == 1) { // switch to system menu bar menubar->hide(); const Fl_Menu_Item *menu = menubar->menu(); - smenubar = new Fl_Sys_Menu_Bar(0,0,0,30); + smenubar = new Fl_Sys_Menu_Bar(0,0,0,30); smenubar->menu(menu); smenubar->callback(test_cb); } @@ -236,6 +236,30 @@ void about_cb(Fl_Widget*, void*) { fl_message("The menubar test app."); } +class Dynamic_Choice: public Fl_Choice { +public: + Dynamic_Choice(int x, int y, int w, int h, const char *label=nullptr) + : Fl_Choice(x, y, w, h, label) { } + int handle(int event) { + static int flip_flop = 0; + if (event == FL_BEFORE_MENU) { + // The following line is legal because we used `copy()` to create a + // writable copy of the menu array when creating this Choice. + Fl_Menu_Item *mi = const_cast(menu()); + if (flip_flop == 1) { + mi[7].flags |= FL_MENU_INACTIVE; + mi[8].flags &= ~FL_MENU_INACTIVE; + flip_flop = 0; + } else { + mi[7].flags &= ~FL_MENU_INACTIVE; + mi[8].flags |= FL_MENU_INACTIVE; + flip_flop = 1; + } + } + return Fl_Choice::handle(event); + } +}; + int main(int argc, char **argv) { for (int i=0; i<99; i++) { char buf[100]; @@ -256,7 +280,10 @@ int main(int argc, char **argv) { mb1.tooltip("this is a menu button"); mb1.callback(test_cb); menus[1] = &mb1; - Fl_Choice ch(300,100,80,25,"&choice:"); ch.menu(pulldown); + Dynamic_Choice ch(300,100,80,25,"&choice:"); + ch.copy(pulldown); + ch.add("Flip"); + ch.add("Flop"); ch.tooltip("this is a choice menu"); ch.callback(test_cb); menus[2] = &ch; -- cgit v1.2.3 From 61c2b798becff0c5b479f399f48fb0387ada4703 Mon Sep 17 00:00:00 2001 From: Matthias Melcher Date: Sat, 29 Mar 2025 23:52:29 +0100 Subject: Adding missing `override`s --- test/color_chooser.cxx | 2 +- test/menubar.cxx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/color_chooser.cxx b/test/color_chooser.cxx index f5c9827cc..3b62fa059 100644 --- a/test/color_chooser.cxx +++ b/test/color_chooser.cxx @@ -89,7 +89,7 @@ class Image_Box: public Fl_Box { public: Image_Box(int x, int y, int w, int h, const char *label = nullptr) : Fl_Box(x, y, w, h, label) { } - int handle(int event) { + int handle(int event) override { if (event == FL_BEFORE_TOOLTIP) { const char *color_name_lut[] = { "blue", "green", "black", "red" }; int quadrant = (Fl::event_x() < x()+w()/2) + 2*(Fl::event_y() < y()+h()/2); diff --git a/test/menubar.cxx b/test/menubar.cxx index 2aeec991c..6cf22458a 100644 --- a/test/menubar.cxx +++ b/test/menubar.cxx @@ -240,7 +240,7 @@ class Dynamic_Choice: public Fl_Choice { public: Dynamic_Choice(int x, int y, int w, int h, const char *label=nullptr) : Fl_Choice(x, y, w, h, label) { } - int handle(int event) { + int handle(int event) override { static int flip_flop = 0; if (event == FL_BEFORE_MENU) { // The following line is legal because we used `copy()` to create a -- cgit v1.2.3 From b2b5e47ede75f0b3df06ed28537b459d79b9f867 Mon Sep 17 00:00:00 2001 From: Matthias Melcher Date: Sun, 30 Mar 2025 00:25:18 +0100 Subject: Somewhat better example for dynamic tooltip. --- test/color_chooser.cxx | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/test/color_chooser.cxx b/test/color_chooser.cxx index 3b62fa059..263cad28a 100644 --- a/test/color_chooser.cxx +++ b/test/color_chooser.cxx @@ -85,16 +85,24 @@ void cb2(Fl_Widget *, void *v) { bx->parent()->redraw(); } -class Image_Box: public Fl_Box { +class Sample_Box: public Fl_Box { public: - Image_Box(int x, int y, int w, int h, const char *label = nullptr) + Sample_Box(int x, int y, int w, int h, const char *label = nullptr) : Fl_Box(x, y, w, h, label) { } int handle(int event) override { if (event == FL_BEFORE_TOOLTIP) { - const char *color_name_lut[] = { "blue", "green", "black", "red" }; - int quadrant = (Fl::event_x() < x()+w()/2) + 2*(Fl::event_y() < y()+h()/2); - char buf[80]; - ::snprintf(buf, 79, "Color %s at x=%d, y=%d", color_name_lut[quadrant], Fl::event_x(), Fl::event_y()); + char buf[128]; + uchar r, g, b; + Fl::get_color(color(), r, g, b); + if ((color()&255) && (color()!=16)) { + ::snprintf(buf, 127, + "Background color is:\n" + "palette no. %d = r:%d, g:%d, b:%d", color(), r, g, b); + } else { + ::snprintf(buf, 127, + "Background color is:\n" + "r:%d, g:%d, b:%d", r, g, b); + } return Fl_Tooltip::override_text(buf); } return Fl_Box::handle(event); @@ -104,7 +112,8 @@ public: int main(int argc, char ** argv) { Fl::set_color(fullcolor_cell,145,159,170); Fl_Window window(400,400); - Fl_Box box(30,30,340,340); + Sample_Box box(30,30,340,340); + box.tooltip("Show RGB values"); box.box(FL_THIN_DOWN_BOX); c = fullcolor_cell; box.color(c); @@ -115,8 +124,7 @@ int main(int argc, char ** argv) { b1.callback(cb1,&box); Fl_Button b2(120,120,180,30,"fl_color_chooser()"); b2.callback(cb2,&box); - Image_Box image_box(160,190,width,height,0); - image_box.tooltip("Image Box"); + Fl_Box image_box(160,190,width,height,0); make_image(); (new Fl_RGB_Image(image, width, height))->label(&image_box); Fl_Box b(160,310,120,30,"Example of fl_draw_image()"); -- cgit v1.2.3 From bd9d1bc03809586d81a547a7a8acce903482910b Mon Sep 17 00:00:00 2001 From: Matthias Melcher Date: Sun, 30 Mar 2025 00:38:10 +0100 Subject: Fixes a couple of compiler warnings on AppleClang. --- fluid/CMakeLists.txt | 13 ------------- src/Fl_Screen_Driver.cxx | 4 ++-- src/Fl_cocoa.mm | 12 ++++++------ 3 files changed, 8 insertions(+), 21 deletions(-) diff --git a/fluid/CMakeLists.txt b/fluid/CMakeLists.txt index bb28c2b9a..d1900b297 100644 --- a/fluid/CMakeLists.txt +++ b/fluid/CMakeLists.txt @@ -255,16 +255,3 @@ if(UNIX) ) endforeach() endif(UNIX) - -# Additional warnings during development - -if(APPLE) - if (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") - target_compile_options(fluid-lib PRIVATE - -Wall -Wextra -Wpedantic -Werror - -Wno-zero-as-null-pointer-constant - -Wno-missing-field-initializers - -Wno-unused-parameter - ) - endif() -endif(APPLE) diff --git a/src/Fl_Screen_Driver.cxx b/src/Fl_Screen_Driver.cxx index 05461a2a1..d7a794726 100644 --- a/src/Fl_Screen_Driver.cxx +++ b/src/Fl_Screen_Driver.cxx @@ -385,7 +385,7 @@ void Fl_Screen_Driver::rescale_all_windows_from_screen(int screen, float f, floa Fl_Window *win = Fl::first_window(); while (win) { if (!win->parent() && (Fl_Window_Driver::driver(win)->screen_num() == screen) && - win->user_data() != &Fl_Screen_Driver::transient_scale_display) { + win->user_data() != (void*)&Fl_Screen_Driver::transient_scale_display) { count++; } win = Fl::next_window(win); @@ -396,7 +396,7 @@ void Fl_Screen_Driver::rescale_all_windows_from_screen(int screen, float f, floa win = Fl::first_window(); // memorize all top-level windows while (win) { if (!win->parent() && (Fl_Window_Driver::driver(win)->screen_num() == screen) && - win->user_data() != &Fl_Screen_Driver::transient_scale_display) { + win->user_data() != (void*)&Fl_Screen_Driver::transient_scale_display) { win_array[i++] = win; } win = Fl::next_window(win); diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm index 468c4b0d0..1e3e68637 100644 --- a/src/Fl_cocoa.mm +++ b/src/Fl_cocoa.mm @@ -686,7 +686,7 @@ void Fl_Cocoa_Screen_Driver::breakMacEventLoop() } return self; } -- (Fl_Window *)getFl_Window; +- (Fl_Window *)getFl_Window { return w; } @@ -1525,13 +1525,13 @@ static FLWindowDelegate *flwindowdelegate_instance = nil; Fl::handle(FL_HIDE, window); fl_unlock_function(); } -- (void)windowWillEnterFullScreen:(NSNotification *)notif; +- (void)windowWillEnterFullScreen:(NSNotification *)notif { FLWindow *nsw = (FLWindow*)[notif object]; Fl_Window *window = [nsw getFl_Window]; window->_set_fullscreen(); } -- (void)windowWillExitFullScreen:(NSNotification *)notif; +- (void)windowWillExitFullScreen:(NSNotification *)notif { FLWindow *nsw = (FLWindow*)[notif object]; Fl_Window *window = [nsw getFl_Window]; @@ -3251,7 +3251,7 @@ void Fl_Cocoa_Window_Driver::makeWindow() w->set_visible(); if ( w->border() || (!w->modal() && !w->tooltip_window() && - w->user_data() != &Fl_Screen_Driver::transient_scale_display) ) Fl::handle(FL_FOCUS, w); + w->user_data() != (void*)&Fl_Screen_Driver::transient_scale_display) ) Fl::handle(FL_FOCUS, w); [cw setDelegate:[FLWindowDelegate singleInstance]]; if (show_iconic()) { show_iconic(0); @@ -4747,7 +4747,7 @@ static CGImageRef capture_decorated_window_SCK(NSWindow *nswin) { } win = Fl::next_window(win); } - CGWindowID target_id = [nswin windowNumber]; + CGWindowID target_id = (CGWindowID)[nswin windowNumber]; NSRect r = [nswin frame]; int W = r.size.width, H = r.size.height; [SCShareableContent getCurrentProcessShareableContentWithCompletionHandler: // macOS 14.4 @@ -4791,7 +4791,7 @@ static CGImageRef capture_decorated_window_SCK(NSWindow *nswin) { while (!capture_err && !capture) CFRunLoopRun(); if (capture_err) return NULL; // ScreenCaptureKit bug cont'd: restore modified styleMasks. - for (int i = 0, count = [xid_array count]; i < count; i++) { + for (int i = 0, count = (int)[xid_array count]; i < count; i++) { NSUInteger mask; [(NSData*)[mask_array objectAtIndex:i] getBytes:&mask length:sizeof(NSUInteger)]; NSWindow *xid = (NSWindow*)[xid_array objectAtIndex:i]; -- cgit v1.2.3 From 0eb6bb8e6d34b39399cda8b768851a3218eb7e2c Mon Sep 17 00:00:00 2001 From: Matthias Melcher Date: Sun, 30 Mar 2025 00:51:34 +0100 Subject: Fixing a few more compiler warnings. --- test/fractals.cxx | 2 +- test/terminal.fl | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/fractals.cxx b/test/fractals.cxx index d9cf9905f..5e3839d03 100644 --- a/test/fractals.cxx +++ b/test/fractals.cxx @@ -70,7 +70,7 @@ int main(int, char**) { # define srand48(x) (srand((x))) #elif defined __APPLE__ # define drand48() (((float) rand())/((float) RAND_MAX)) -# define srand48(x) (srand((x))) +# define srand48(x) (srand((int)(x))) #endif typedef enum { NOTALLOWED, MOUNTAIN, TREE, ISLAND, BIGMTN, STEM, LEAF, diff --git a/test/terminal.fl b/test/terminal.fl index b2c0d4d1f..3c9186b68 100644 --- a/test/terminal.fl +++ b/test/terminal.fl @@ -452,8 +452,7 @@ const char *test[] = { }; if (reset) { index = 0; return 0; } -return show_test(test, index);} {selected - } +return show_test(test, index);} {} } Function {test_esc_rgbcolors(bool reset)} { comment {--- 0020: Test RGB Colors} return_type {static int} @@ -1373,7 +1372,7 @@ for ( int t=0; t 0) G_tty->append(s, bytes); // write block to terminal, handles utf8 + else if (bytes > 0) G_tty->append(s, (int)bytes); // write block to terminal, handles utf8 else break; // pipe closed } PCLOSE(fp); G_tty->append_ascii("\\033[33;2m<>\\033[0m\\n"); -G_tty->redraw();} {} +G_tty->redraw();} {selected + } } decl {////// GUI LAYOUT //////} {private local } -- cgit v1.2.3 From f4978a014997656b4592c2b3b866865f76d390ea Mon Sep 17 00:00:00 2001 From: Matthias Melcher Date: Tue, 1 Apr 2025 17:00:51 +0200 Subject: Adding the FL_MENU_CHATTY flag to Fl_Menu_Item. If set, menu items will also call the callback when highlighting changes. The reason is given with Fl::callback_reason(). #941 --- FL/Fl_Menu_Item.H | 28 +++++++++++++++++++++++----- src/Fl_MacOS_Sys_Menu_Bar.mm | 2 +- src/Fl_Menu.cxx | 21 ++++++++++++++++++++- src/Fl_Menu_.cxx | 7 +++++-- test/menubar.cxx | 16 ++++++++++++++-- 5 files changed, 63 insertions(+), 11 deletions(-) diff --git a/FL/Fl_Menu_Item.H b/FL/Fl_Menu_Item.H index 3073dd2d0..6eaf0a9d2 100644 --- a/FL/Fl_Menu_Item.H +++ b/FL/Fl_Menu_Item.H @@ -34,7 +34,8 @@ enum { // values for flags: FL_SUBMENU_POINTER = 0x20, ///< Indicates user_data() is a pointer to another menu array FL_SUBMENU = 0x40, ///< Item is a submenu to other items FL_MENU_DIVIDER = 0x80, ///< Creates divider line below this item. Also ends a group of radio buttons - FL_MENU_HORIZONTAL = 0x100 ///< ??? -- reserved, internal (do not use) + FL_MENU_HORIZONTAL = 0x100, ///< reserved, do not use + FL_MENU_CHATTY = 0x200 ///< Menu Item receives additional callbacks ///< Note: \b ALL other bits in \p flags are reserved: do not use them for your own purposes! }; @@ -67,7 +68,8 @@ class Fl_Menu_; FL_SUBMENU_POINTER = 0x20, // Indicates user_data() is a pointer to another menu array FL_SUBMENU = 0x40, // This item is a submenu to other items FL_MENU_DIVIDER = 0x80, // Creates divider line below this item. Also ends a group of radio buttons. - FL_MENU_HORIZONTAL = 0x100 // ??? -- reserved, internal (do not use) + FL_MENU_HORIZONTAL = 0x100 // reserved, do not use + FL_MENU_CHATTY = 0x200 ///< Menu Item receives additional callbacks }; \endcode @@ -120,6 +122,16 @@ class Fl_Menu_; variants copies the entire menu to internal storage. Using the memory of a static menu array after that would access unused (but not released) memory and thus have no effect. + + When a menu item is selected by the user and a callback is set, the callback + will be called with FL_REASON_SELECTED. The Fl_Widget pointer is set to the + widget that opened the menu, a copy of the menu item's user data. If no menu + item callback is set, the callback of the managing widget is called instead. + + If the FL_MENU_CHATTY flag is set, the menu item callback may be called for + additional reasons. When a menu item is highlighted, the callback is called + with FL_REASON_GOT_FOCUS. If it is no longer highlighted, + FL_REASON_LOST_FOCUS is sent. */ struct FL_EXPORT Fl_Menu_Item { const char *text; ///< menu item text, returned by label() @@ -490,14 +502,18 @@ struct FL_EXPORT Fl_Menu_Item { The callback is called with the stored user_data() as its second argument. You must first check that callback() is non-zero before calling this. */ - void do_callback(Fl_Widget* o) const {Fl::callback_reason_=FL_REASON_SELECTED; callback_(o, user_data_);} + void do_callback(Fl_Widget* o, Fl_Callback_Reason reason=FL_REASON_UNKNOWN) const { + Fl::callback_reason_ = reason; callback_(o, user_data_); + } /** Calls the Fl_Menu_Item item's callback, and provides the Fl_Widget argument. This call overrides the callback's second argument with the given value \p arg. You must first check that callback() is non-zero before calling this. */ - void do_callback(Fl_Widget* o,void* arg) const {Fl::callback_reason_=FL_REASON_SELECTED; callback_(o, arg);} + void do_callback(Fl_Widget* o, void* arg, Fl_Callback_Reason reason=FL_REASON_UNKNOWN) const { + Fl::callback_reason_ = reason; callback_(o, arg); + } /** Calls the Fl_Menu_Item item's callback, and provides the Fl_Widget argument. @@ -506,7 +522,9 @@ struct FL_EXPORT Fl_Menu_Item { the callback. You must first check that callback() is non-zero before calling this. */ - void do_callback(Fl_Widget* o,long arg) const {Fl::callback_reason_=FL_REASON_SELECTED; callback_(o, (void*)(fl_intptr_t)arg);} + void do_callback(Fl_Widget* o, long arg, Fl_Callback_Reason reason=FL_REASON_UNKNOWN) const { + Fl::callback_reason_ = FL_REASON_SELECTED; callback_(o, (void*)(fl_intptr_t)arg); + } /** Back compatibility only. \deprecated diff --git a/src/Fl_MacOS_Sys_Menu_Bar.mm b/src/Fl_MacOS_Sys_Menu_Bar.mm index b76deb27e..87c5089cd 100644 --- a/src/Fl_MacOS_Sys_Menu_Bar.mm +++ b/src/Fl_MacOS_Sys_Menu_Bar.mm @@ -167,7 +167,7 @@ const char *Fl_Mac_App_Menu::quit = "Quit %@"; { fl_lock_function(); Fl_Menu_Item *item = (Fl_Menu_Item *)[(NSData*)[self representedObject] bytes]; - if ( item && item->callback() ) item->do_callback(NULL); + if ( item && item->callback() ) item->do_callback(NULL, FL_REASON_SELECTED); fl_unlock_function(); } - (void) setKeyEquivalentModifierMask:(int)value diff --git a/src/Fl_Menu.cxx b/src/Fl_Menu.cxx index 500b20a5c..a91666ad3 100644 --- a/src/Fl_Menu.cxx +++ b/src/Fl_Menu.cxx @@ -146,6 +146,7 @@ class menuwindow : public window_with_items { public: menutitle* title; int handle(int) FL_OVERRIDE; + void hide() override; int itemheight; // zero == menubar int numitems; int selected; @@ -480,6 +481,11 @@ menuwindow::~menuwindow() { delete title; } +void menuwindow::hide() { + set_selected(-1); + window_with_items::hide(); +} + void menuwindow::position(int X, int Y) { if (title) {title->position(X, title->y()+Y-y());} Fl_Menu_Window::position(X, Y); @@ -592,7 +598,20 @@ void menuwindow::draw() { } void menuwindow::set_selected(int n) { - if (n != selected) {selected = n; damage(FL_DAMAGE_CHILD);} + if (n != selected) { + if ((selected!=-1) && (menu)) { + const Fl_Menu_Item *mi = menu->next(selected); + if ((mi) && (mi->callback_) && (mi->flags & FL_MENU_CHATTY)) + mi->do_callback(this, FL_REASON_LOST_FOCUS); + } + selected = n; + if ((selected!=-1) && (menu)) { + const Fl_Menu_Item *mi = menu->next(selected); + if ((mi) && (mi->callback_) && (mi->flags & FL_MENU_CHATTY)) + mi->do_callback(this, FL_REASON_GOT_FOCUS); + } + damage(FL_DAMAGE_CHILD); + } } //////////////////////////////////////////////////////////////// diff --git a/src/Fl_Menu_.cxx b/src/Fl_Menu_.cxx index 20964e748..6a34278ff 100644 --- a/src/Fl_Menu_.cxx +++ b/src/Fl_Menu_.cxx @@ -401,8 +401,11 @@ const Fl_Menu_Item* Fl_Menu_::picked(const Fl_Menu_Item* v) { value_ = v; if (when()&(FL_WHEN_CHANGED|FL_WHEN_RELEASE)) { if (changed() || when()&FL_WHEN_NOT_CHANGED) { - if (value_ && value_->callback_) value_->do_callback((Fl_Widget*)this); - else do_callback(); + if (value_ && value_->callback_) { + value_->do_callback((Fl_Widget*)this, value_->user_data(), FL_REASON_SELECTED); + } else { + do_callback(FL_REASON_SELECTED); + } } } } diff --git a/test/menubar.cxx b/test/menubar.cxx index 6cf22458a..355921eba 100644 --- a/test/menubar.cxx +++ b/test/menubar.cxx @@ -61,7 +61,19 @@ void test_cb(Fl_Widget* w, void*) { G_tty->printf("%s\n", m->label()); } -void quit_cb(Fl_Widget*, void*) {exit(0);} +void quit_cb(Fl_Widget*, void*) { + switch (Fl::callback_reason()) { + case FL_REASON_SELECTED: + exit(0); + case FL_REASON_GOT_FOCUS: + G_tty->printf("Selecting this menu item will quit this application!\n"); + break; + case FL_REASON_LOST_FOCUS: + G_tty->printf("Risk of quitting averted.\n"); + break; + default: break; + } +} Fl_Menu_Item hugemenu[100]; @@ -70,7 +82,7 @@ Fl_Menu_Item menutable[] = { {"&File",0,0,0,FL_SUBMENU}, {"&Open", FL_ALT+'o', 0, 0, FL_MENU_INACTIVE}, {"&Close", 0, 0}, - {"&Quit", FL_ALT+'q', quit_cb, 0, FL_MENU_DIVIDER}, + {"&Quit", FL_ALT+'q', quit_cb, 0, FL_MENU_DIVIDER|FL_MENU_CHATTY}, #if (OVERRIDE_SCALING_SHORTCUTS) {"CTRL/0", FL_COMMAND+'0', 0}, -- cgit v1.2.3 From 8b28e38942ce8b61966da90af644c9948a007eda Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Sun, 30 Mar 2025 17:39:57 -0400 Subject: options.cmake: Check Threads_FOUND, not CMAKE_HAVE_THREADS_LIBRARY The former's been available since CMake v2.8 and documented since v3.17; the latter was never documented and quietly went away in CMake v3.24. --- CMake/options.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMake/options.cmake b/CMake/options.cmake index d2fa392f7..8411b92ec 100644 --- a/CMake/options.cmake +++ b/CMake/options.cmake @@ -739,11 +739,11 @@ if(FLTK_USE_PTHREADS) include(FindThreads) - if(CMAKE_HAVE_THREADS_LIBRARY) + if(Threads_FOUND) add_definitions("-D_THREAD_SAFE -D_REENTRANT") set(USE_THREADS 1) set(FLTK_THREADS_FOUND TRUE) - endif(CMAKE_HAVE_THREADS_LIBRARY) + endif(Threads_FOUND) if(CMAKE_USE_PTHREADS_INIT AND NOT WIN32) set(HAVE_PTHREAD 1) -- cgit v1.2.3 From 794d493eb685674a964cee1b68d81ee455987252 Mon Sep 17 00:00:00 2001 From: Albrecht Schlosser Date: Wed, 2 Apr 2025 19:59:56 +0200 Subject: CMake: check version for some properties in fl_debug_target() Debug only, if fl_debug_target() is used: Prior to CMake 3.19 some properties of "INTERFACE_LIBRARY targets" can't be read with get_property(). These properties are now excluded if the CMake version is lower than 3.19. --- CMake/fl_debug_var.cmake | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/CMake/fl_debug_var.cmake b/CMake/fl_debug_var.cmake index 815e97dc1..d583d7d0c 100644 --- a/CMake/fl_debug_var.cmake +++ b/CMake/fl_debug_var.cmake @@ -117,16 +117,20 @@ function(fl_debug_target name) ### INTERFACE_LOCATION) ### endif() - list(APPEND _props + if(NOT _type STREQUAL "INTERFACE_LIBRARY" OR CMAKE_VERSION VERSION_GREATER_EQUAL "3.19") + # Before 3.19: "INTERFACE_LIBRARY targets may only have whitelisted properties" + list(APPEND _props INCLUDE_DIRECTORIES LINK_DIRECTORIES LINK_LIBRARIES - COMPILE_DEFINITIONS - INTERFACE_COMPILE_DEFINITIONS - INTERFACE_COMPILE_FEATURES - INTERFACE_INCLUDE_DIRECTORIES - INTERFACE_LINK_DIRECTORIES - INTERFACE_LINK_LIBRARIES) + COMPILE_DEFINITIONS) + endif() + + list(APPEND _props + INTERFACE_COMPILE_DEFINITIONS + INTERFACE_INCLUDE_DIRECTORIES + INTERFACE_LINK_DIRECTORIES + INTERFACE_LINK_LIBRARIES) foreach(prop ${_props}) get_target_property(${prop} ${name} ${prop}) -- cgit v1.2.3 From 678c85027294c0ae5162d02b20a59fde758ac77a Mon Sep 17 00:00:00 2001 From: "Aaron M. Ucko" Date: Sun, 30 Mar 2025 20:56:57 -0400 Subject: Use CMake's built-in timestamp formatting. It notably honors SOURCE_DATE_EPOCH if set, making for reproducible output. For even better reproducibility, use UTC. (Unlike the date command's output, the result is already always in English.) Extend this approach to the book, introducing appropriately formatted PDF_DATE and TODAY variables for its PDF metadata and title page respectively and making make_pdf configurable. --- documentation/CMakeLists.txt | 26 ++++++++++++--------- documentation/make_pdf | 41 --------------------------------- documentation/make_pdf.in | 46 +++++++++++++++++++++++++++++++++++++ documentation/src/fltk-title.tex.in | 2 +- 4 files changed, 62 insertions(+), 53 deletions(-) delete mode 100755 documentation/make_pdf create mode 100755 documentation/make_pdf.in diff --git a/documentation/CMakeLists.txt b/documentation/CMakeLists.txt index f93d0cba5..6cd1d1462 100644 --- a/documentation/CMakeLists.txt +++ b/documentation/CMakeLists.txt @@ -37,16 +37,12 @@ if(GENERATE_DOCS) # create required variables - execute_process(COMMAND date "+%Y" - OUTPUT_VARIABLE YEAR - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - + string(TIMESTAMP YEAR "%Y" UTC) # note: current locale is used for abbreviated month - execute_process(COMMAND date "+%b %d, %Y" - OUTPUT_VARIABLE CURRENT_DATE - OUTPUT_STRIP_TRAILING_WHITESPACE - ) + string(TIMESTAMP CURRENT_DATE "%b %d, %Y" UTC) + string(TIMESTAMP PDF_DATE "D:%Y%m%d%H%M%SZ" UTC) + string(TIMESTAMP TODAY "%B %d, %Y" UTC) + string(REPLACE " 0" " " TODAY "${TODAY}") # Find "short" doxygen version if it was built from Git # Note: this is still needed in CMake 3.15 but later CMake versions @@ -77,6 +73,8 @@ if(GENERATE_DOCS) if(0) # debug fl_debug_var(YEAR) fl_debug_var(CURRENT_DATE) + fl_debug_var(PDF_DATE) + fl_debug_var(TODAY) fl_debug_var(FLTK_GIT_REVISION) fl_debug_var(DOXYGEN_FOUND) fl_debug_var(DOXYGEN_EXECUTABLE) @@ -179,7 +177,7 @@ if(FLTK_BUILD_PDF_DOCS) COMMENT "Converting ${DOXYFILE} to doxygen version ${DOXYGEN_VERSION_SHORT}" VERBATIM ) - # generate LaTeX title fltk-title.tex + # generate LaTeX title fltk-title.tex and make_pdf script configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/src/fltk-title.tex.in @@ -187,6 +185,12 @@ if(FLTK_BUILD_PDF_DOCS) @ONLY ) + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/make_pdf.in + ${CMAKE_CURRENT_BINARY_DIR}/make_pdf + @ONLY + ) + # generate fltk.pdf add_custom_command( @@ -196,7 +200,7 @@ if(FLTK_BUILD_PDF_DOCS) ${CMAKE_CURRENT_BINARY_DIR}/fltk-title.tex ${CMAKE_CURRENT_BINARY_DIR}/fltk-book.tex COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYFILE} - COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/make_pdf + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/make_pdf COMMAND cp -f latex/refman.pdf fltk.pdf DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${DOXYFILE} ${CMAKE_CURRENT_BINARY_DIR}/fltk-title.tex diff --git a/documentation/make_pdf b/documentation/make_pdf deleted file mode 100755 index a5487bae4..000000000 --- a/documentation/make_pdf +++ /dev/null @@ -1,41 +0,0 @@ -#! /bin/sh -# -# Makefile helper script for the Fast Light Tool Kit (FLTK) documentation. -# -# Copyright 1998-2020 by Bill Spitzak and others. -# -# This library is free software. Distribution and use rights are outlined in -# the file "COPYING" which should have been included with this file. If this -# file is missing or damaged, see the license at: -# -# https://www.fltk.org/COPYING.php -# -# Please see the following page on how to report bugs and issues: -# -# https://www.fltk.org/bugs.php -# - -# This script generates latex/refman.pdf after doxygen has been executed. -# -# Input: run `doxygen Doxybook' (creates files in subdirectory latex) -# Output: latex/refman.pdf (if successful) -# -# Next step: cp -f latex/refman.pdf fltk.pdf (why is this extra step needed ?) -# -# Working directory: fltk/documentation -# -# Used in: Makefile and CMakeLists.txt - -( cd latex - pdflatex --interaction=nonstopmode refman.tex - makeindex refman.idx - pdflatex --interaction=nonstopmode refman.tex - latex_count=5 - while egrep -s 'Rerun (LaTeX|to get cross-references right)' refman.log \ - && [ $latex_count -gt 0 ] - do - echo "Rerunning pdflatex ..." - pdflatex --interaction=nonstopmode refman.tex - latex_count=`expr $latex_count - 1` - done - cd ..) > pdfall.log 2>&1 diff --git a/documentation/make_pdf.in b/documentation/make_pdf.in new file mode 100755 index 000000000..c0e5fad8a --- /dev/null +++ b/documentation/make_pdf.in @@ -0,0 +1,46 @@ +#! /bin/sh +# +# Makefile helper script for the Fast Light Tool Kit (FLTK) documentation. +# +# Copyright 1998-2020 by Bill Spitzak and others. +# +# This library is free software. Distribution and use rights are outlined in +# the file "COPYING" which should have been included with this file. If this +# file is missing or damaged, see the license at: +# +# https://www.fltk.org/COPYING.php +# +# Please see the following page on how to report bugs and issues: +# +# https://www.fltk.org/bugs.php +# + +# This script generates latex/refman.pdf after doxygen has been executed. +# +# Input: run `doxygen Doxybook' (creates files in subdirectory latex) +# Output: latex/refman.pdf (if successful) +# +# Next step: cp -f latex/refman.pdf fltk.pdf (why is this extra step needed ?) +# +# Working directory: fltk/documentation +# +# Used in: Makefile and CMakeLists.txt + +run_pdflatex() { + pdflatex --interaction=nonstopmode \ + "\pdfinfo{/CreationDate(@PDF_DATE@)/ModDate(@PDF_DATE@)}\input{refman.tex}" +} + +( cd latex + run_pdflatex + makeindex refman.idx + run_pdflatex + latex_count=5 + while egrep -s 'Rerun (LaTeX|to get cross-references right)' refman.log \ + && [ $latex_count -gt 0 ] + do + echo "Rerunning pdflatex ..." + pdflatex --interaction=nonstopmode refman.tex + latex_count=`expr $latex_count - 1` + done + cd ..) > pdfall.log 2>&1 diff --git a/documentation/src/fltk-title.tex.in b/documentation/src/fltk-title.tex.in index cc7f853c9..5096461c2 100644 --- a/documentation/src/fltk-title.tex.in +++ b/documentation/src/fltk-title.tex.in @@ -25,7 +25,7 @@ provided this copyright and permission notice are preserved.}\\ \vspace*{1.5cm} {\large Generated by Doxygen @DOXY_VERSION@}\\ \vspace*{0.5cm} -\today{}\\ +@TODAY@\\ \vspace*{0.5cm} {\small Git revision @FLTK_GIT_REVISION@}\\ \end{center} -- cgit v1.2.3