Skip to main content
Fract’ol provides intuitive keyboard and mouse controls for exploring fractals in real-time. All controls trigger an immediate re-render of the fractal.

Keyboard Controls

The keyboard handler is implemented in events.c:26:
int key_handler(int keysym, t_fractol *fractol)
{
    if (keysym == XK_Escape)
        close_handler(fractol);
    if (keysym == XK_Left || keysym == XK_a)
        fractol->shift_x -= (0.5 * fractol->zoom);
    else if (keysym == XK_Right || keysym == XK_d)
        fractol->shift_x += (0.5 * fractol->zoom);
    else if (keysym == XK_Up || keysym == XK_w)
        fractol->shift_y += (0.5 * fractol->zoom);
    else if (keysym == XK_Down || keysym == XK_s)
        fractol->shift_y -= (0.5 * fractol->zoom);
    else if (keysym == XK_plus)
        fractol->iterations_definition += 5;
    else if (keysym == XK_minus)
        fractol->iterations_definition -= 5;
    fractol_render(fractol);
    return (0);
}

Panning Controls

Arrow Keys

Move in any direction
  • ← Left Arrow: Pan left
  • → Right Arrow: Pan right
  • ↑ Up Arrow: Pan up
  • ↓ Down Arrow: Pan down
Each press moves by 0.5 * zoom units

WASD Keys

Alternative movement
  • A: Pan left (same as ←)
  • D: Pan right (same as →)
  • W: Pan up (same as ↑)
  • S: Pan down (same as ↓)
Gaming-style navigation
The panning distance is zoom-aware: when zoomed in, you pan less distance per keypress, giving you finer control over navigation.

Detail Controls

+ (Plus)

Increase detailAdds 5 iterations to iterations_definitionReveals more detail at fractal boundaries but renders slower

- (Minus)

Decrease detailRemoves 5 iterations from iterations_definitionFaster rendering but less detail, useful for quick exploration
The default iteration count is 30. Deep zoom levels may require 100+ iterations to properly render fine details.

System Controls

ESC

Exit the program
if (keysym == XK_Escape)
    close_handler(fractol);
Cleanly destroys the window, image, and MLX connection before exiting.

Mouse Controls

The mouse handler enables smooth zooming functionality:
int mouse_handler(int button, int x, int y, t_fractol *fractol)
{
    (void)x;
    (void)y;
    if (button == Button4)
    {
        fractol->zoom *= 0.95;  // Zoom in
    }
    else if (button == Button5)
    {
        fractol->zoom *= 1.05;  // Zoom out
    }
    fractol_render(fractol);
    return (0);
}

Scroll Up

Zoom In (Button4)Multiplies zoom by 0.95Decreases the visible area, magnifying the fractal

Scroll Down

Zoom Out (Button5)Multiplies zoom by 1.05Increases the visible area, showing more of the fractal
The zoom factor changes by 5% per scroll. Multiple rapid scrolls create smooth zoom animations. The zoom is centered on the current view, not the mouse position.

Complete Control Reference

Quick Reference Table

ControlKeysymActionEffect
XK_LeftPan leftshift_x -= 0.5 * zoom
XK_RightPan rightshift_x += 0.5 * zoom
XK_UpPan upshift_y += 0.5 * zoom
XK_DownPan downshift_y -= 0.5 * zoom
AXK_aPan leftSame as ←
DXK_dPan rightSame as →
WXK_wPan upSame as ↑
SXK_sPan downSame as ↓
+XK_plusAdd detailiterations_definition += 5
-XK_minusRemove detailiterations_definition -= 5
ESCXK_EscapeExit programCleanup and exit
Scroll UpButton4Zoom inzoom *= 0.95
Scroll DownButton5Zoom outzoom *= 1.05

Event System Architecture

The controls are hooked into the MiniLibX event system during initialization:
static void events_init(t_fractol *fractol)
{
    // Keyboard events
    mlx_hook(fractol->mlx_window, KeyPress, KeyPressMask,
        key_handler, fractol);
    
    // Mouse button events (scroll wheel)
    mlx_hook(fractol->mlx_window, ButtonPress,
        ButtonPressMask, mouse_handler, fractol);
    
    // Window close event (X button)
    mlx_hook(fractol->mlx_window, DestroyNotify, StructureNotifyMask,
        close_handler, fractol);
}
All event handlers receive the t_fractol structure, allowing them to directly modify rendering parameters and trigger re-renders.
  1. Start zoomed out to see the overall structure
  2. Use keyboard panning to position interesting features in the center
  3. Scroll to zoom in gradually
  4. Increase iterations (+) as you zoom deeper
  5. Pan to nearby features to explore the area
  • Decrease iterations (-) when navigating quickly
  • Zoom out slightly if rendering is too slow
  • Increase iterations only when examining details
  • The 2000x1500 window size provides good balance
  • Small zoom factor (5% per scroll) enables fine control
  • Zoom-aware panning maintains control at all zoom levels
  • Multiple rapid keypresses for faster movement
  • ESC always works even if the program appears frozen
  1. Identify target region
  2. Center it using WASD/arrows
  3. Zoom in with multiple scroll ups
  4. Press + several times to add iterations (e.g., 50-100)
  5. Wait for render to complete
  6. Fine-tune position and zoom

Keysym Values

The controls use X11 keysym constants defined in <X11/keysym.h>:
#include <X11/keysym.h>

// Used keysyms in the project:
XK_Escape    // ESC key
XK_Left      // Left arrow
XK_Right     // Right arrow
XK_Up        // Up arrow
XK_Down      // Down arrow
XK_a         // A key
XK_d         // D key
XK_w         // W key
XK_s         // S key
XK_plus      // + key
XK_minus     // - key
Mouse buttons use X11 button constants:
Button4      // Scroll wheel up
Button5      // Scroll wheel down
These are standard X11 constants, ensuring compatibility across Linux systems using X Window System.

Real-Time Rendering

Every control action triggers an immediate re-render:
fractol_render(fractol);  // Called after every parameter change
The rendering process:
  1. Parameters are modified (zoom, shift_x, shift_y, iterations)
  2. fractol_render() iterates through all 2000×1500 pixels
  3. Each pixel is computed using the escape-time algorithm
  4. The completed image is displayed to the window
Render time depends on iteration count and zoom level. At high iteration counts (100+), rendering may take several seconds.

Build docs developers (and LLMs) love